[svn] GpgOL - r238 - in trunk: . doc po src

svn author wk cvs at cvs.gnupg.org
Wed Mar 19 19:30:16 CET 2008


Author: wk
Date: 2008-03-19 19:30:14 +0100 (Wed, 19 Mar 2008)
New Revision: 238

Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/autogen.sh
   trunk/configure.ac
   trunk/doc/gpgol.texi
   trunk/po/de.po
   trunk/po/sv.po
   trunk/src/ChangeLog
   trunk/src/common.h
   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:
Implemented opaque signed+encrypted.
Implemented old-style PGP with attachments.


[The diff below has been truncated]

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/ChangeLog	2008-03-19 18:30:14 UTC (rev 238)
@@ -1,3 +1,7 @@
+2008-03-19  Werner Koch  <wk at g10code.com>
+
+	* Release 0.10.9.
+
 2008-03-18  Werner Koch  <wk at g10code.com>
 
 	* Release 0.10.8.

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/ChangeLog	2008-03-19 18:30:14 UTC (rev 238)
@@ -1,3 +1,19 @@
+2008-03-19  Werner Koch  <wk at g10code.com>
+
+	* mapihelp.cpp (mapi_change_message_class): Look into
+	multipart/mixed for PGP messages.
+
+	* mapihelp.cpp (mapi_get_attach): Add arg UNPROTECT and changed
+	all callers.
+	* common.h (DBG_MIME_PARSER, DBG_MIME_DATA): New.
+	* mimeparser.c (debug_mime_parser, debug_mime_data): New to
+	replace DEBUG_PARSER.
+	(struct mime_context): Add field is_opaque_signed. 
+	(t2body): Set it.
+	(mime_decrypt): Handle an embedded opaque signed S/MIME part.
+	(mime_verify_opaque): Add arg INBUFER, INBUFFERLEN and
+	START_PART_COUNTER.
+
 2008-03-18  Werner Koch  <wk at g10code.com>
 
 	* mimeparser.c (message_cb): Clear all mimestruct fields.  Fixes

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/NEWS	2008-03-19 18:30:14 UTC (rev 238)
@@ -1,3 +1,12 @@
+Noteworthy changes for version 0.10.9 (2008-03-19)
+=================================================
+
+ * Decrypt opaque signed and encrypted S/MIME mails.
+
+ * Handle old-style PGP message with attachments.  Note that the
+   signature verification currently may indicate a bad signature.
+
+
 Noteworthy changes for version 0.10.8 (2008-03-18)
 =================================================
 

Modified: trunk/autogen.sh
===================================================================
--- trunk/autogen.sh	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/autogen.sh	2008-03-19 18:30:14 UTC (rev 238)
@@ -160,4 +160,4 @@
 echo "Running autoconf${FORCE} ..."
 $AUTOCONF${FORCE}
 
-echo "You may now run \"./configure --enable-maintainer-mode && make\"."
+echo "You may now run \"./autogen.sh --build-w32 && make\"."

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/configure.ac	2008-03-19 18:30:14 UTC (rev 238)
@@ -16,7 +16,7 @@
 # Remember to change the version number immediately *after* a release.
 # 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.8])
+m4_define([my_version], [0.10.9])
 m4_define([my_issvn], [no])
 
 m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \

Modified: trunk/doc/gpgol.texi
===================================================================
--- trunk/doc/gpgol.texi	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/doc/gpgol.texi	2008-03-19 18:30:14 UTC (rev 238)
@@ -673,6 +673,10 @@
 Tell about resource allocation.
 @item 64 (0x0040)
 Tell about command events.
+ at item 128 (0x0080)
+Tell what the MIME parser is doing
+ at item 256 (0x0100)
+Print data lines while parsing MIME.
 @end table
 You may use the regular C-syntax for entering the value.
 

Modified: trunk/po/de.po  [not shown]
Modified: trunk/po/sv.po  [not shown]
Modified: trunk/src/common.h
===================================================================
--- trunk/src/common.h	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/common.h	2008-03-19 18:30:14 UTC (rev 238)
@@ -148,14 +148,16 @@
 
 /* Bit values used for extra log file verbosity.  Value 1 is reserved
    to enable debug menu options.  */
-#define DBG_IOWORKER        2
-#define DBG_IOWORKER_EXTRA  4
-#define DBG_FILTER          8
-#define DBG_FILTER_EXTRA   16 
-#define DBG_MEMORY         32
-#define DBG_COMMANDS       64
+#define DBG_IOWORKER       (1<<1)
+#define DBG_IOWORKER_EXTRA (1<<2) 
+#define DBG_FILTER         (1<<3)
+#define DBG_FILTER_EXTRA   (1<<4) 
+#define DBG_MEMORY         (1<<5)
+#define DBG_COMMANDS       (1<<6)
+#define DBG_MIME_PARSER    (1<<7)
+#define DBG_MIME_DATA      (1<<8)
 
-/* Macros to used in conditionals to enabel debug output.  */
+/* Macros to used in conditionals to enable debug output.  */
 #define debug_commands    (opt.enable_debug & DBG_COMMANDS)
 
 

Modified: trunk/src/mapihelp.cpp
===================================================================
--- trunk/src/mapihelp.cpp	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/mapihelp.cpp	2008-03-19 18:30:14 UTC (rev 238)
@@ -384,8 +384,8 @@
 
 
 /* Look at the body of the MESSAGE and try to figure out whether this
-   is a supported PGP message.  Returns the new message class on
-   return or NULL if not.  */
+   is a supported PGP message.  Returns the new message class or NULL
+   if it does not look like a PGP message.  */
 static char *
 get_msgcls_from_pgp_lines (LPMESSAGE message)
 {
@@ -720,6 +720,13 @@
                 {
                   newvalue = get_msgcls_from_pgp_lines (message);
                 }
+              else if (!strcmp (ct, "multipart/mixed"))
+                {
+                  /* It is quite common to have a multipart/mixed mail
+                     with separate encrypted PGP parts.  Look at the
+                     body to decide.  */
+                  newvalue = get_msgcls_from_pgp_lines (message);
+                }
               
               xfree (ct);
             }
@@ -1600,9 +1607,11 @@
 
 
 /* Return an attachment as a malloced buffer.  The size of the buffer
-   will be stored at R_NBYTES.  Returns NULL on failure. */
+   will be stored at R_NBYTES.  If unprotect is true, the atatchment
+   will be unprotected.  Returns NULL on failure. */
 char *
-mapi_get_attach (LPMESSAGE message, mapi_attach_item_t *item, size_t *r_nbytes)
+mapi_get_attach (LPMESSAGE message, int unprotect, 
+                 mapi_attach_item_t *item, size_t *r_nbytes)
 {
   HRESULT hr;
   LPATTACH att;
@@ -1625,7 +1634,7 @@
       return NULL;
     }
 
-  buffer = attach_to_buffer (att, r_nbytes, 0, NULL);
+  buffer = attach_to_buffer (att, r_nbytes, unprotect, NULL);
   att->Release ();
 
   return buffer;

Modified: trunk/src/mapihelp.h
===================================================================
--- trunk/src/mapihelp.h	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/mapihelp.h	2008-03-19 18:30:14 UTC (rev 238)
@@ -117,7 +117,7 @@
 LPSTREAM mapi_get_attach_as_stream (LPMESSAGE message, 
                                     mapi_attach_item_t *item, 
                                     LPATTACH *r_attach);
-char *mapi_get_attach (LPMESSAGE message, 
+char *mapi_get_attach (LPMESSAGE message, int unprotect,
                        mapi_attach_item_t *item, size_t *r_nbytes);
 int mapi_mark_moss_attach (LPMESSAGE message, mapi_attach_item_t *item);
 int mapi_has_sig_status (LPMESSAGE msg);

Modified: trunk/src/message.cpp
===================================================================
--- trunk/src/message.cpp	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/message.cpp	2008-03-19 18:30:14 UTC (rev 238)
@@ -330,7 +330,7 @@
 
 /* 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 guarnateed
+   received the valid length of that buffer; the buffer is guaranteed
    to be Nul terminated.  */
 static char *
 pgp_mime_from_clearsigned (LPSTREAM input, size_t *outputlen)
@@ -649,7 +649,7 @@
           return -1; /* No original attachment - this should not happen.  */
         }
 
-      inbuf = mapi_get_attach (message, table+0, &inbuflen);
+      inbuf = mapi_get_attach (message, 0, table+0, &inbuflen);
       if (!inbuf)
         {
           mapi_release_attach_table (table);
@@ -658,7 +658,8 @@
     }
 
   if (opaquestream)
-    err = mime_verify_opaque (protocol, opaquestream, message, hwnd, 0);
+    err = mime_verify_opaque (protocol, opaquestream,
+                              NULL, 0, message, hwnd, 0, 0);
   else
     err = mime_verify (protocol, inbuf, inbuflen, message, hwnd, 0);
   log_debug ("mime_verify%s returned %d", opaquestream? "_opaque":"", err);
@@ -877,7 +878,7 @@
          However, due to problems with Outlook overwriting the body of
          the message after decryption, we need to save the body away
          before decrypting it.  We then always look for that original
-         body atatchment and create one if it does not exist.  */
+         body attachment or create one if it does not exist.  */
       part1_idx = -1;
       table = mapi_create_attach_table (message, 0);
       if (!table)

Modified: trunk/src/mimemaker.c
===================================================================
--- trunk/src/mimemaker.c	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/mimemaker.c	2008-03-19 18:30:14 UTC (rev 238)
@@ -903,7 +903,7 @@
       if (table[idx].attach_type == ATTACHTYPE_UNKNOWN
           && table[idx].method == ATTACH_BY_VALUE)
         {
-          buffer = mapi_get_attach (message, table+idx, &buflen);
+          buffer = mapi_get_attach (message, 0, table+idx, &buflen);
           if (!buffer)
             log_debug ("Attachment at index %d not found\n", idx);
           else

Modified: trunk/src/mimeparser.c
===================================================================
--- trunk/src/mimeparser.c	2008-03-18 11:24:27 UTC (rev 237)
+++ trunk/src/mimeparser.c	2008-03-19 18:30:14 UTC (rev 238)
@@ -43,13 +43,15 @@
 #include "serpent.h"
 #include "mimeparser.h"
 
-/* Define the next to get extra debug message for the MIME parser.  */
-#define DEBUG_PARSER 1
 
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
                                      SRCNAME, __func__, __LINE__); \
                         } while (0)
 
+#define debug_mime_parser (opt.enable_debug & (DBG_MIME_PARSER|DBG_MIME_DATA))
+#define debug_mime_data (opt.enable_debug & DBG_MIME_DATA)
+
+
 static const char oid_mimetag[] =
     {0x2A, 0x86, 0x48, 0x86, 0xf7, 0x14, 0x03, 0x0a, 0x04};
 
@@ -112,6 +114,7 @@
   int is_qp_encoded;      /* Current part is QP encoded. */
   int is_base64_encoded;  /* Current part is base 64 encoded. */
   int is_body;            /* The current part belongs to the body.  */
+  int is_opaque_signed;   /* Flag indicating opaque signed S/MIME. */
   protocol_t protocol;    /* The detected crypto protocol.  */
 
   int part_counter;       /* Counts the number of processed parts. */
@@ -213,9 +216,8 @@
     case RFC822PARSE_EPILOGUE: s= "Epilogue"; break;
     default: s= "[unknown event]"; break;
     }
-#ifdef DEBUG_PARSER
-  log_debug ("%s: ctx=%p, rfc822 event %s\n", SRCNAME, ctx, s);
-#endif
+  if (debug_mime_parser)
+    log_debug ("%s: ctx=%p, rfc822 event %s\n", SRCNAME, ctx, s);
 }
 
 
@@ -233,9 +235,8 @@
   LPSTREAM to = NULL;
   LPUNKNOWN punk;
 
-#ifdef DEBUG_PARSER
-  log_debug ("%s:%s: for ctx=%p is_body=%d", SRCNAME, __func__, ctx, is_body);
-#endif
+  if (debug_mime_parser)
+    log_debug ("%s:%s: for ctx=%p is_body=%d", SRCNAME, __func__, ctx,is_body);
 
   /* Just in case something has not been finished, do it here. */
   if (ctx->outstream)
@@ -480,9 +481,8 @@
   HRESULT hr;
   int retval = -1;
 
-#ifdef DEBUG_PARSER
-  log_debug ("%s:%s: for ctx=%p cancel=%d", SRCNAME, __func__, ctx, cancel);
-#endif
+  if (debug_mime_parser)
+    log_debug ("%s:%s: for ctx=%p cancel=%d", SRCNAME, __func__, ctx, cancel);
 
   if (ctx->outstream && ctx->is_body && !ctx->body_saved.outstream)
     {
@@ -755,10 +755,9 @@
       ctsub  = "plain";
     }
 
-#ifdef DEBUG_PARSER  
-  log_debug ("%s:%s: ctx=%p, ct=`%s/%s'\n",
-             SRCNAME, __func__, ctx, ctmain, ctsub);
-#endif
+  if (debug_mime_parser)
+    log_debug ("%s:%s: ctx=%p, ct=`%s/%s'\n",
+               SRCNAME, __func__, ctx, ctmain, ctsub);
 
   s = rfc822parse_query_parameter (field, "charset", 0);
   if (s)
@@ -830,17 +829,30 @@
     }
   else /* Other type. */
     {
+      /* Check whether this attachment is an opaque signed S/MIME
+         part.  We use a counter to later check that tehre is only one
+         such part. */
+      if (!strcmp (ctmain, "application") && !strcmp (ctsub, "pkcs7-mime"))
+        {
+          const char *smtype = rfc822parse_query_parameter (field,
+                                                            "smime-type", 0);
+          if (smtype && !strcmp (smtype, "signed-data"))
+            ctx->is_opaque_signed++;
+        }
+
       if (!ctx->preview)
         ctx->collect_attachment = 1;
     }
   rfc822parse_release_field (field); /* (Content-type) */
   ctx->in_data = 1;
 
-#ifdef DEBUG_PARSER
-  log_debug ("%s: this body: nesting=%d partno=%d is_text=%d charset=\"%s\"\n",
-             SRCNAME, ctx->nesting_level, ctx->part_counter, is_text, 
-             ctx->mimestruct_cur->charset?ctx->mimestruct_cur->charset:"");
-#endif
+  if (debug_mime_parser)
+    log_debug ("%s:%s: this body: nesting=%d partno=%d is_text=%d, is_opq=%d"
+               " charset=\"%s\"\n",
+               SRCNAME, __func__, 
+               ctx->nesting_level, ctx->part_counter, is_text, 
+               ctx->is_opaque_signed,
+               ctx->mimestruct_cur->charset?ctx->mimestruct_cur->charset:"");
 
   /* If this is a text part, decide whether we treat it as our body. */
   if (is_text)
@@ -884,9 +896,8 @@
         {
           /* We already got one body and thus we can continue that
              last attachment.  */
-#ifdef DEBUG_PARSER
-          log_debug ("%s:%s: continuing body part\n", SRCNAME, __func__);
-#endif
+          if (debug_mime_parser)
+            log_debug ("%s:%s: continuing body part\n", SRCNAME, __func__);
           ctx->is_body = 1;
           ctx->outstream = ctx->body_saved.outstream;
           ctx->mapi_attach = ctx->body_saved.mapi_attach;
@@ -927,10 +938,9 @@
         return 0; /*  We need to skip the OPEN event.  */
       if (!ctx->body_seen)
         {
-#ifdef DEBUG_PARSER
-          log_debug ("%s:%s: assuming this is plain text without headers\n",
-                     SRCNAME, __func__);
-#endif
+          if (debug_mime_parser)
+            log_debug ("%s:%s: assuming this is plain text without headers\n",
+                       SRCNAME, __func__);
           ctx->in_data = 1;
           ctx->collect_attachment = 2; /* 2 so we don't skip the first line. */
           ctx->body_seen = 1;
@@ -1050,8 +1060,9 @@
           if (pos && ctx->linebuf[pos-1] == '\r')
             pos--;
 
-/*           log_debug ("%s:%s: ctx=%p, line=`%.*s'\n", */
-/*                      SRCNAME, __func__, ctx, (int)pos, ctx->linebuf); */
+          if (debug_mime_data)
+            log_debug ("%s:%s: ctx=%p, line=`%.*s'\n",
+                       SRCNAME, __func__, ctx, (int)pos, ctx->linebuf);
           if (rfc822parse_insert (ctx->msg, ctx->linebuf, pos))
             {
               log_error ("%s: ctx=%p, rfc822 parser failed: %s\n",
@@ -1191,7 +1202,9 @@
   while ( (s = memchr (message, '\n', messagelen)) )
     {
       len = s - message + 1;
-/*       log_debug ("passing '%.*s'\n", (int)len, message); */
+      if (debug_mime_data)
+        log_debug ("%s:%s: passing '%.*s'\n", 
+                   SRCNAME, __func__, (int)len, message);
       plaintext_handler (ctx, message, len);
       if (ctx->parser_error || ctx->line_too_long)
         {
@@ -1284,13 +1297,17 @@
 
 
 /* A special version of mime_verify which works only for S/MIME opaque
-   signed messages.  The message is expected to be a binary data
-   stream with a CMS signature.  This function passes the entire
-   message to the crypto engine and then parses the (cleartext) output
-   for rendering the data.  */
+   signed messages.  The message is expected to be a binary CMS
+   signature eityher as an ISTREAM (if instream is not NULL) or
+   provided in a buffer (INBUFFER and INBUFERLEN).  This function
+   passes the entire message to the crypto engine and then parses the
+   (cleartext) output for rendering the data.  START_PART_COUNTER
+   should normally be set to 0. */
 int
 mime_verify_opaque (protocol_t protocol, LPSTREAM instream, 
-                    LPMESSAGE mapi_message, HWND hwnd, int preview_mode)
+                    const char *inbuffer, size_t inbufferlen,
+                    LPMESSAGE mapi_message, HWND hwnd, int preview_mode,
+                    int start_part_counter)
 {
   gpg_error_t err = 0;
   mime_context_t ctx;
@@ -1298,6 +1315,10 @@
 
   log_debug ("%s:%s: enter (protocol=%d)", SRCNAME, __func__, protocol);
 
+  if ((instream && (inbuffer || inbufferlen))
+      || (!instream && !inbuffer))
+    return gpg_error (GPG_ERR_INV_VALUE);
+
   if (protocol != PROTOCOL_SMIME)
     return gpg_error (GPG_ERR_INV_VALUE);
 
@@ -1308,6 +1329,7 @@
   ctx->verify_mode = 0;
   ctx->mapi_message = mapi_message;
   ctx->mimestruct_tail = &ctx->mimestruct;
+  ctx->part_counter = start_part_counter;
 
   ctx->msg = rfc822parse_open (message_cb, ctx);
   if (!ctx->msg)
@@ -1323,28 +1345,36 @@
   if ((err=engine_verify_start (filter, hwnd, NULL, 0, protocol)))
     goto leave;
 
-  /* Filter the stream.  */
-  do
+  if (instream)
     {
-      HRESULT hr;
-      ULONG nread;
-      char buffer[4096];
+      /* Filter the stream.  */
+      do
+        {
+          HRESULT hr;
+          ULONG nread;
+          char buffer[4096];
       
-      hr = IStream_Read (instream, buffer, sizeof buffer, &nread);
-      if (hr)
-        {
-          log_error ("%s:%s: IStream::Read failed: hr=%#lx", 
-                     SRCNAME, __func__, hr);
-          err = gpg_error (GPG_ERR_EIO);
+          hr = IStream_Read (instream, buffer, sizeof buffer, &nread);
+          if (hr)
+            {
+              log_error ("%s:%s: IStream::Read failed: hr=%#lx", 
+                         SRCNAME, __func__, hr);
+              err = gpg_error (GPG_ERR_EIO);
+            }
+          else if (nread)
+            {
+              err = engine_filter (filter, buffer, nread);
+            }
+          else
+            break; /* EOF */
         }
-      else if (nread)
-        {
-          err = engine_filter (filter, buffer, nread);
-        }
-      else
-        break; /* EOF */
+      while (!err);
     }
-  while (!err);
+  else
+    {
+      /* Filter the buffer.  */
+      err = engine_filter (filter, inbuffer, inbufferlen);
+    }
   if (err)
     goto leave;
 
@@ -1437,18 +1467,17 @@
       ctsub  = "plain";
     }
 
-#ifdef DEBUG_PARSER  
-  log_debug ("%s:%s: ctx=%p, ct=`%s/%s'\n",
-             SRCNAME, __func__, ctx, ctmain, ctsub);
-#endif
+  if (debug_mime_parser)
+    log_debug ("%s:%s: ctx=%p, ct=`%s/%s'\n",
+               SRCNAME, __func__, ctx, ctmain, ctsub);
+
   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
+  if (debug_mime_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);
 




More information about the Gnupg-commits mailing list