[svn] GpgOL - r215 - in trunk: . src

svn author wk cvs at cvs.gnupg.org
Wed Feb 6 15:01:47 CET 2008


Author: wk
Date: 2008-02-06 15:01:45 +0100 (Wed, 06 Feb 2008)
New Revision: 215

Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/TODO
   trunk/configure.ac
   trunk/src/ChangeLog
   trunk/src/mapihelp.cpp
   trunk/src/mapihelp.h
   trunk/src/message.cpp
   trunk/src/mimemaker.c
   trunk/src/mimeparser.c
   trunk/src/mimeparser.h
Log:
Preparing for a new release.


[The diff below has been truncated]

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/ChangeLog	2008-02-06 14:01:45 UTC (rev 215)
@@ -1,3 +1,7 @@
+2008-02-06  Werner Koch  <wk at g10code.com>
+
+	Released 0.10.4 development version.
+
 2007-12-10  Werner Koch  <wk at g10code.com>
 
 	Released 0.10.3 development version.

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/src/ChangeLog	2008-02-06 14:01:45 UTC (rev 215)
@@ -1,3 +1,19 @@
+2008-02-06  Werner Koch  <wk at g10code.com>
+
+	* mimeparser.c (mime_decrypt): New arg IS_RFC822.
+	* message.cpp (message_decrypt): Add code to see whether to use
+	the new arg.
+
+2008-02-01  Werner Koch  <wk at g10code.com>
+
+	* mimeparser.c (ciphertext_handler, ciphermessage_cb)
+	(ciphermessage_t2body): New.
+	(mime_decrypt): Use an rfc822 parser to pass the message to the
+	engine.
+
+	* mapihelp.cpp (mapi_get_attach_as_stream): Add arg R_ATTACH.
+	(mapi_set_attach_hidden): New.
+
 2008-01-31  Werner Koch  <wk at g10code.com>
 
 	* message.cpp (message_verify): Check that the body attachment is

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/NEWS	2008-02-06 14:01:45 UTC (rev 215)
@@ -1,4 +1,4 @@
-Noteworthy changes for version 0.10.4
+Noteworthy changes for version 0.10.4 (2008-02-06)
 ==================================================
 
  UNDER HEAVY DEVELOPMENT - DO NOT USE FOR PRODUCTION!

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/TODO	2008-02-06 14:01:45 UTC (rev 215)
@@ -24,5 +24,5 @@
   presented file names and decrypt them only on OpenSzFile.  Need to
   find some documentation first.
 
-* We need to use the micalg as retruned my Kleopatra.
+* We need to use the micalg as returned by the UI-server.
 

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/configure.ac	2008-02-06 14:01:45 UTC (rev 215)
@@ -1,5 +1,5 @@
 # configure.ac - for GpgOL
-# Copyright (C) 2005, 2006, 2007 g10 Code GmbH
+# Copyright (C) 2005, 2006, 2007, 2008 g10 Code GmbH
 #
 # This file is free software; as a special exception the author gives
 # unlimited permission to copy and/or distribute it, with or without
@@ -17,7 +17,7 @@
 # Set my_issvn to "yes" for non-released code.  Remember to run an
 # "svn up" and "autogen.sh" right before creating a distribution.
 m4_define([my_version], [0.10.4])
-m4_define([my_issvn], [yes])
+m4_define([my_issvn], [no])
 
 m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \
             || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')]))

Modified: trunk/src/mapihelp.cpp
===================================================================
--- trunk/src/mapihelp.cpp	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/src/mapihelp.cpp	2008-02-06 14:01:45 UTC (rev 215)
@@ -1,5 +1,5 @@
 /* mapihelp.cpp - Helper functions for MAPI
- *	Copyright (C) 2005, 2007 g10 Code GmbH
+ *	Copyright (C) 2005, 2007, 2008 g10 Code GmbH
  * 
  * This file is part of GpgOL.
  * 
@@ -1180,14 +1180,20 @@
 
 
 /* Return an attachment as a new IStream object.  Returns NULL on
-   failure. */
+   failure.  If R_ATATCH is not NULL the actual attachment will not be
+   released by stored at that address; the caller needs to release it
+   in this case.  */
 LPSTREAM
-mapi_get_attach_as_stream (LPMESSAGE message, mapi_attach_item_t *item)
+mapi_get_attach_as_stream (LPMESSAGE message, mapi_attach_item_t *item,
+                           LPATTACH *r_attach)
 {
   HRESULT hr;
   LPATTACH att;
   LPSTREAM stream;
 
+  if (r_attach)
+    *r_attach = NULL;
+
   if (!item || item->end_of_table || item->mapipos == -1)
     return NULL;
 
@@ -1215,7 +1221,10 @@
       return NULL;
     }
 
-  att->Release ();
+  if (r_attach)
+    *r_attach = att;
+  else
+    att->Release ();
 
   return stream;
 }
@@ -1362,7 +1371,7 @@
 
 
 /* Mark this attachment as the orginal MOSS message.  We set a custom
-   property as weel ast the hidden hidden flag on ot..  */
+   property as well as the hidden hidden flag.  */
 int 
 mapi_mark_moss_attach (LPMESSAGE message, mapi_attach_item_t *item)
 {
@@ -1427,7 +1436,48 @@
 }
 
 
+/* If the hidden property has not been set on ATTACH, set it and save
+   the changes. */
+int 
+mapi_set_attach_hidden (LPATTACH attach)
+{
+  int retval = -1;
+  HRESULT hr;
+  LPSPropValue propval;
+  SPropValue prop;
 
+  hr = HrGetOneProp ((LPMAPIPROP)attach, PR_ATTACHMENT_HIDDEN, &propval);
+  if (SUCCEEDED (hr) 
+      && PROP_TYPE (propval->ulPropTag) == PT_BOOLEAN
+      && propval->Value.b)
+    return 0;/* Already set to hidden. */
+
+  prop.ulPropTag = PR_ATTACHMENT_HIDDEN;
+  prop.Value.b = TRUE;
+  hr = HrSetOneProp (attach, &prop);
+  if (hr)
+    {
+      log_error ("%s:%s: can't set hidden attach flag: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+  
+  hr = attach->SaveChanges (KEEP_OPEN_READWRITE);
+  if (hr)
+    {
+      log_error ("%s:%s: SaveChanges(attachment) failed: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+  
+  retval = 0;
+    
+ leave:
+  return retval;
+}
+
+
+
 /* Returns True if MESSAGE has the GpgOL Sig Status property.  */
 int
 mapi_has_sig_status (LPMESSAGE msg)

Modified: trunk/src/mapihelp.h
===================================================================
--- trunk/src/mapihelp.h	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/src/mapihelp.h	2008-02-06 14:01:45 UTC (rev 215)
@@ -80,6 +80,10 @@
 };
 typedef struct mapi_attach_item_s mapi_attach_item_t;
 
+/* The filename of the attachment we create as the result of sign or
+   encrypt operation.  Don't change this name as some tests rely on
+   it.  */
+#define MIMEATTACHFILENAME "gpgolXXX.dat"
 
 
 void log_mapi_property (LPMESSAGE message, ULONG prop, const char *propname);
@@ -104,7 +108,8 @@
 mapi_attach_item_t *mapi_create_attach_table (LPMESSAGE message, int fast);
 void mapi_release_attach_table (mapi_attach_item_t *table);
 LPSTREAM mapi_get_attach_as_stream (LPMESSAGE message, 
-                                    mapi_attach_item_t *item);
+                                    mapi_attach_item_t *item, 
+                                    LPATTACH *r_attach);
 char *mapi_get_attach (LPMESSAGE message, 
                        mapi_attach_item_t *item, size_t *r_nbytes);
 int mapi_mark_moss_attach (LPMESSAGE message, mapi_attach_item_t *item);
@@ -116,6 +121,8 @@
 
 int mapi_set_gpgol_msg_class (LPMESSAGE message, const char *name);
 
+int  mapi_set_attach_hidden (LPATTACH attach);
+
 char *mapi_get_mime_info (LPMESSAGE msg);
 
 char *mapi_get_message_content_type (LPMESSAGE message, 

Modified: trunk/src/message.cpp
===================================================================
--- trunk/src/message.cpp	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/src/message.cpp	2008-02-06 14:01:45 UTC (rev 215)
@@ -598,6 +598,9 @@
   gpg_error_t err;
   int is_opaque = 0;
   protocol_t protocol;
+  LPATTACH saved_attach = NULL;
+  int need_saved_attach = 0;
+  int need_rfc822_parser = 0;
 
   switch (msgtype)
     {
@@ -632,7 +635,6 @@
     }
   else
     {
-  
       /* PGP/MIME or S/MIME stuff.  */
       table = mapi_create_attach_table (message, 0);
       if (!table)
@@ -641,7 +643,7 @@
       if (is_opaque)
         {
           /* S/MIME opaque encrypted message: We expect one
-             attachment.  As we don't know ether we are called the
+             attachment.  As we don't know wether we are called the
              first time, we first try to find this attachment by
              looking at all attachments.  Only if this fails we
              identify it by its order.  */
@@ -650,11 +652,12 @@
             if (table[tblidx].attach_type == ATTACHTYPE_MOSSTEMPL)
               {
                 /* This attachment has been generated by us in the
-                   course of sendeing a new message.  The content will
+                   course of sending a new message.  The content will
                    be multipart/signed because we used this to trick
                    out OL.  We stop here and use this part for further
                    processing.  */
                 part2_idx = tblidx;
+                need_rfc822_parser = 1;
                 break;
               }
             else if (table[tblidx].attach_type == ATTACHTYPE_MOSS)
@@ -692,7 +695,7 @@
         {
           /* Multipart/encrypted message: We expect 2 attachments.
              The first one with the version number and the second one
-             with the ciphertext.  As we don't know ether we are
+             with the ciphertext.  As we don't know wether we are
              called the first time, we first try to find these
              attachments by looking at all attachments.  Only if this
              fails we identify them by their order (i.e. the first 2
@@ -732,8 +735,32 @@
                   mapi_mark_moss_attach (message, table+part2_idx);
                 }
             }
-          if (part1_idx == -1 || part2_idx == -1)
+
+
+          if (part1_idx == -1 || part2_idx == -1 
+              && !table[0].end_of_table && table[1].end_of_table
+              && table[0].attach_type == ATTACHTYPE_MOSS
+              && table[0].filename 
+              && !strcmp (table[0].filename, MIMEATTACHFILENAME))
             {
+              /* This is likely a PGP/MIME created by us.  Due to the
+                 way we created that message, the MAPI derived content
+                 type is wrong and there is only one attachtment
+                 (gpgolXXX.dat).  We simply assume that it is PGP/MIME
+                 encrypted and pass it on to the mime parser.  We also
+                 keep the attachment open so that we can later set it
+                 to hidden if not yet done.  I can't remember whether
+                 it is possible to set the hidden attribute when
+                 creating the message - probably not.  Thus we take
+                 care of it here. */
+              log_debug ("%s:%s: "
+                         "assuming self-created PGP/MIME encrypted message",
+                         SRCNAME, __func__);
+              part2_idx = 0;
+              need_saved_attach = 1;
+            }
+          else if (part1_idx == -1 || part2_idx == -1)
+            {
               log_debug ("%s:%s: this is not a PGP/MIME encrypted message",
                          SRCNAME, __func__);
               goto leave;
@@ -741,12 +768,15 @@
           protocol = PROTOCOL_OPENPGP;
         }
       
-      cipherstream = mapi_get_attach_as_stream (message, table+part2_idx);
+      cipherstream = mapi_get_attach_as_stream (message, table+part2_idx,
+                                                need_saved_attach? 
+                                                &saved_attach : NULL );
       if (!cipherstream)
         goto leave; /* Problem getting the attachment.  */
     }
 
-  err = mime_decrypt (protocol, cipherstream, message, hwnd, 0);
+  err = mime_decrypt (protocol, cipherstream, message, 
+                      need_rfc822_parser, hwnd, 0);
   log_debug ("mime_decrypt returned %d (%s)", err, gpg_strerror (err));
   if (err)
     {
@@ -755,10 +785,18 @@
       snprintf (buf, sizeof buf, "Decryption failed (%s)", gpg_strerror (err));
       MessageBox (NULL, buf, "GpgOL", MB_ICONINFORMATION|MB_OK);
     }
+  else
+    {
+      if (saved_attach)
+        mapi_set_attach_hidden (saved_attach);
+    }
   cipherstream->Release ();
   retval = 0;
 
+
  leave:
+  if (saved_attach)
+    saved_attach->Release ();
   mapi_release_attach_table (table);
   return retval;
 }

Modified: trunk/src/mimemaker.c
===================================================================
--- trunk/src/mimemaker.c	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/src/mimemaker.c	2008-02-06 14:01:45 UTC (rev 215)
@@ -44,9 +44,6 @@
                                      SRCNAME, __func__, __LINE__); \
                         } while (0)
 
-/* The filename of the attachment we create as the result of sign or
-   encrypt operation.  */
-#define MIMEATTACHFILENAME "gpgolXXX.dat"
 
 static const char oid_mimetag[] =
     {0x2A, 0x86, 0x48, 0x86, 0xf7, 0x14, 0x03, 0x0a, 0x04};

Modified: trunk/src/mimeparser.c
===================================================================
--- trunk/src/mimeparser.c	2008-01-31 15:46:49 UTC (rev 214)
+++ trunk/src/mimeparser.c	2008-02-06 14:01:45 UTC (rev 215)
@@ -120,6 +120,8 @@
                              working on a MIME message and not just on
                              plain rfc822 message.  */
   
+  engine_filter_t outfilter; /* Fiter as used by ciphertext_handler.  */
+
   /* A linked list describing the structure of the mime message.  This
      list gets build up while parsing the message.  */
   mimestruct_item_t mimestruct;
@@ -732,9 +734,7 @@
 
   /* Process the Content-type and all its parameters.  */
   ctmain = ctsub = NULL;
-  field = rfc822parse_parse_field (msg, "GnuPG-Content-Type", -1);
-  if (!field)
-    field = rfc822parse_parse_field (msg, "Content-Type", -1);
+  field = rfc822parse_parse_field (msg, "Content-Type", -1);
   if (field)
     ctmain = rfc822parse_query_media_type (field, &ctsub);
   if (!ctmain)
@@ -1140,7 +1140,7 @@
   while ( (s = memchr (message, '\n', messagelen)) )
     {
       len = s - message + 1;
-      log_debug ("passing '%.*s'\n", (int)len, message);
+/*       log_debug ("passing '%.*s'\n", (int)len, message); */
       plaintext_handler (ctx, message, len);
       if (ctx->parser_error || ctx->line_too_long)
         {
@@ -1233,20 +1233,219 @@
 
 
 
+/* Process the transition to body event in the decryption parser.
+
+   This means we have received the empty line indicating the body and
+   should now check the headers to see what to do about this part.  */
+static int
+ciphermessage_t2body (mime_context_t ctx, rfc822parse_t msg)
+{
+  rfc822parse_field_t field;
+  const char *ctmain, *ctsub;
+  size_t off;
+  char *p;
+  int is_text = 0;
+        
+  /* Figure out the encoding.  */
+  ctx->is_qp_encoded = 0;
+  ctx->is_base64_encoded = 0;
+  p = rfc822parse_get_field (msg, "Content-Transfer-Encoding", -1, &off);
+  if (p)
+    {
+      if (!stricmp (p+off, "quoted-printable"))
+        ctx->is_qp_encoded = 1;
+      else if (!stricmp (p+off, "base64"))
+        {
+          ctx->is_base64_encoded = 1;
+          b64_init (&ctx->base64);
+        }
+      free (p);
+    }
+
+  /* Process the Content-type and all its parameters.  */
+  /* Fixme: Currently we don't make any use of it but consider all the
+     content to be the encrypted data.  */
+  ctmain = ctsub = NULL;
+  field = rfc822parse_parse_field (msg, "Content-Type", -1);
+  if (field)
+    ctmain = rfc822parse_query_media_type (field, &ctsub);
+  if (!ctmain)
+    {
+      /* Either there is no content type field or it is faulty; in
+         both cases we fall back to text/plain.  */
+      ctmain = "text";
+      ctsub  = "plain";
+    }
+
+#ifdef DEBUG_PARSER  
+  log_debug ("%s:%s: ctx=%p, ct=`%s/%s'\n",
+             SRCNAME, __func__, ctx, ctmain, ctsub);
+#endif
+  rfc822parse_release_field (field); /* (Content-type) */
+  ctx->in_data = 1;
+
+#ifdef DEBUG_PARSER
+  log_debug ("%s:%s: this body: nesting=%d part_counter=%d is_text=%d\n",
+             SRCNAME, __func__, 
+             ctx->nesting_level, ctx->part_counter, is_text);
+#endif
+
+
+  return 0;
+}
+
+/* This routine gets called by the RFC822 decryption parser for all
+   kind of events.  Should return 0 on success or -1 as well as
+   setting errno on failure.  */
+static int
+ciphermessage_cb (void *opaque, rfc822parse_event_t event, rfc822parse_t msg)
+{
+  int retval = 0;
+  mime_context_t decctx = opaque;
+
+  debug_message_event (decctx, event);
+
+  switch (event)
+    {
+    case RFC822PARSE_T2BODY:
+      retval = ciphermessage_t2body (decctx, msg);
+      break;
+
+    case RFC822PARSE_LEVEL_DOWN:
+      decctx->nesting_level++;
+      break;
+
+    case RFC822PARSE_LEVEL_UP:
+      if (decctx->nesting_level)
+        decctx->nesting_level--;
+      else 
+        {
+          log_error ("%s: decctx=%p, invalid structure: bad nesting level\n",
+                     SRCNAME, decctx);
+          decctx->parser_error = 1;
+        }
+      break;
+    
+    case RFC822PARSE_BOUNDARY:
+    case RFC822PARSE_LAST_BOUNDARY:
+      decctx->any_boundary = 1;
+      decctx->in_data = 0;
+      break;
+    
+    case RFC822PARSE_BEGIN_HEADER:
+      decctx->part_counter++;
+      break;
+
+    default:  /* Ignore all other events. */
+      break;
+    }
+
+  return retval;
+}
+
+
+/* This handler is called by us with the MIME message containing the
+   ciphertext. */
+static int
+ciphertext_handler (void *handle, const void *buffer, size_t size)
+{
+  mime_context_t ctx = handle;
+  const char *s;
+  size_t nleft, pos, len;
+  gpg_error_t err;
+
+  s = buffer;
+  pos = ctx->linebufpos;
+  nleft = size;
+  for (; nleft ; nleft--, s++)
+    {
+      if (pos >= ctx->linebufsize)
+        {
+          log_error ("%s:%s: ctx=%p, rfc822 parser failed: line too long\n",
+                     SRCNAME, __func__, ctx);
+          ctx->line_too_long = 1;
+          return -1; /* Error. */
+        }
+      if (*s != '\n')
+        ctx->linebuf[pos++] = *s;
+      else
+        { /* Got a complete line.  Remove the last CR.  */
+          if (pos && ctx->linebuf[pos-1] == '\r')




More information about the Gnupg-commits mailing list