[svn] GpgOL - r269 - trunk/src

svn author wk cvs at cvs.gnupg.org
Thu Oct 16 14:42:39 CEST 2008


Author: wk
Date: 2008-10-16 14:42:39 +0200 (Thu, 16 Oct 2008)
New Revision: 269

Modified:
   trunk/src/ChangeLog
   trunk/src/engine-assuan.c
   trunk/src/mapihelp.cpp
Log:
Support --protocol for SENDER assuan command.
Refactored some code in mapihelp.cpp.
Decide between signedData, evenelopedData and unknown in
is_really_cms_encryped.


Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-09-30 13:33:44 UTC (rev 268)
+++ trunk/src/ChangeLog	2008-10-16 12:42:39 UTC (rev 269)
@@ -1,3 +1,19 @@
+2008-10-16  Werner Koch  <wk at g10code.com>
+
+	* mapihelp.cpp (is_really_cms_encrypted): Extend to detect unknown
+	message types.
+	(mapi_change_message_class): Adjust for this change.
+	(mapi_change_message_class): Factor code out to ...
+	(change_message_class_ipm_note) 
+	(change_message_class_ipm_note_smime) 
+	(change_message_class_ipm_note_smime_multipartsigned) 
+	(change_message_class_ipm_note_secure_cex): New.
+
+2008-10-15  Werner Koch  <wk at g10code.com>
+
+	* engine-assuan.c (op_assuan_sign): Send the new --protocl option
+	to the server.
+
 2008-09-30  Werner Koch  <wk at g10code.com>
 
 	* mapihelp.cpp (mapi_change_message_class): Special handling for

Modified: trunk/src/engine-assuan.c
===================================================================
--- trunk/src/engine-assuan.c	2008-09-30 13:33:44 UTC (rev 268)
+++ trunk/src/engine-assuan.c	2008-10-16 12:42:39 UTC (rev 269)
@@ -1810,13 +1810,16 @@
     goto leave;
 
   /* We always send the SENDER command because it allows us to figure
-     out the protocol to use.  In case the UI server faisl to send the
-     protocol we fall back to OpenPGP.  */
+     out the protocol to use.  In case the UI server fails to send the
+     protocol we fall back to OpenPGP.  The --protocol option isused
+     to given the server a hint on what protocol we would prefer. */
   suggested_protocol = PROTOCOL_UNKNOWN;
   if (!sender)
     sender = "<kleopatra-does-not-allow-an-empty-arg at example.net>";
-  snprintf (line, sizeof line, "SENDER%s%s",
-            sender? " -- ":"", sender?sender:"");
+  snprintf (line, sizeof line, "SENDER%s%s -- %s",
+            protocol_name? " --protocol=":"",
+            protocol_name? protocol_name:"",
+            sender? sender:"");
   err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL,
                          prep_foo_status_cb, &suggested_protocol);
   if (err)

Modified: trunk/src/mapihelp.cpp
===================================================================
--- trunk/src/mapihelp.cpp	2008-09-30 13:33:44 UTC (rev 268)
+++ trunk/src/mapihelp.cpp	2008-10-16 12:42:39 UTC (rev 269)
@@ -562,8 +562,10 @@
 
 /* Check whether the message is really a CMS encrypted message.  
    We check here whether the message is really encrypted by looking at
-   the object identifier inside the CMS data.  Returns true if the
-   message is really encrypted.
+   the object identifier inside the CMS data.  Returns:
+    -1 := Unknown message type,
+     0 := The message is signed,
+     1 := The message is encrypted.
 
    This function is required for two reasons: 
 
@@ -574,6 +576,10 @@
  
    2. If the smime-type parameter is missing we need another way to
       decide whether to decrypt or to verify.
+
+   3. Some messages lack a PR_TRANSPORT_MESSAGE_HEADERS and thus it is
+      not possible to deduce the message type from the mail headers.
+      This function may be used to identify the message anyway.
  */
 static int
 is_really_cms_encrypted (LPMESSAGE message)
@@ -583,7 +589,7 @@
   LPMAPITABLE mapitable;
   LPSRowSet   mapirows;
   unsigned int pos, n_attach;
-  int is_encrypted = 0;
+  int result = -1; /* Unknown.  */
   LPATTACH att = NULL;
   LPSTREAM stream = NULL;
   char buffer[24];  /* 24 bytes are more than enough to peek at.
@@ -616,7 +622,7 @@
     {
       FreeProws (mapirows);
       mapitable->Release ();
-      log_debug ("%s:%s: not just one attachments", SRCNAME, __func__);
+      log_debug ("%s:%s: not just one attachment", SRCNAME, __func__);
       return 0;
     }
   pos = 0;
@@ -678,11 +684,16 @@
   if (!(ti.cls == MY_ASN_CLASS_UNIVERSAL && ti.tag == MY_ASN_TAG_OBJECT_ID
         && !ti.is_cons && ti.length) || ti.length > n)
     goto leave;
-  /* Now is this enveloped data (1.2.840.113549.1.7.3)?  */
-  if (ti.length == 9 && !memcmp (p, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03", 9))
-    is_encrypted = 1;
-
-
+  /* Now is this enveloped data (1.2.840.113549.1.7.3)
+                 or signed data (1.2.840.113549.1.7.2) ? */
+  if (ti.length == 9)
+    {
+      if (!memcmp (p, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03", 9))
+        result = 1; /* Encrypted.  */
+      else if (!memcmp (p, "\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02", 9))
+        result = 0; /* Signed.  */
+    }
+  
  leave:
   if (stream)
     stream->Release ();
@@ -690,11 +701,258 @@
     att->Release ();
   FreeProws (mapirows);
   mapitable->Release ();
-  return !!is_encrypted;
+  return result;
 }
 
 
+/* Helper for mapi_change_message_class.  Returns the new message
+   class as an allocated string.
 
+   Most message today are of the message class "IPM.Note".  However a
+   PGP/MIME encrypted message also has this class.  We need to see
+   whether we can detect such a mail right here and change the message
+   class accordingly. */
+static char *
+change_message_class_ipm_note (LPMESSAGE message)
+{
+  char *newvalue = NULL;
+  char *ct, *proto;
+
+  ct = mapi_get_message_content_type (message, &proto, NULL);
+  if (!ct)
+    log_debug ("%s:%s: message has no content type", SRCNAME, __func__);
+  else
+    {
+      log_debug ("%s:%s: content type is '%s'", SRCNAME, __func__, ct);
+      if (proto)
+        {
+          log_debug ("%s:%s:     protocol is '%s'", SRCNAME, __func__, proto);
+          
+          if (!strcmp (ct, "multipart/encrypted")
+              && !strcmp (proto, "application/pgp-encrypted"))
+            {
+              newvalue = xstrdup ("IPM.Note.GpgOL.MultipartEncrypted");
+            }
+          else if (!strcmp (ct, "multipart/signed")
+                   && !strcmp (proto, "application/pgp-signature"))
+            {
+              /* Sometimes we receive a PGP/MIME signed message with a
+                 class IPM.Note.  */
+              newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
+            }
+          xfree (proto);
+        }
+      else if (!strcmp (ct, "text/plain"))
+        {
+          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);
+    }
+
+  return newvalue;
+}
+
+/* Helper for mapi_change_message_class.  Returns the new message
+   class as an allocated string.
+
+   This function is used for the message class "IPM.Note.SMIME".  It
+   indicates an S/MIME opaque encrypted or signed message.  This may
+   also be an PGP/MIME mail. */
+static char *
+change_message_class_ipm_note_smime (LPMESSAGE message)
+{
+  char *newvalue = NULL;
+  char *ct, *proto, *smtype;
+  
+  ct = mapi_get_message_content_type (message, &proto, &smtype);
+  if (!ct)
+    log_debug ("%s:%s: message has no content type", SRCNAME, __func__);
+  else
+    {
+      log_debug ("%s:%s: content type is '%s'", SRCNAME, __func__, ct);
+      if (proto 
+          && !strcmp (ct, "multipart/signed")
+          && !strcmp (proto, "application/pgp-signature"))
+        {
+          newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
+        }
+      else if (!opt.enable_smime)
+        ; /* S/MIME not enabled; thus no further checks.  */
+      else if (smtype)
+        {
+          log_debug ("%s:%s:   smime-type is '%s'", SRCNAME, __func__, smtype);
+          
+          if (!strcmp (ct, "application/pkcs7-mime")
+              || !strcmp (ct, "application/x-pkcs7-mime"))
+            {
+              if (!strcmp (smtype, "signed-data"))
+                newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
+              else if (!strcmp (smtype, "enveloped-data"))
+                newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
+            }
+        }
+      else
+        {
+          /* No smime type.  The filename parameter is often not
+             reliable, thus we better look into the message to see if
+             it is encrypted and assume an opaque signed one if this
+             is not the case.  */
+          switch (is_really_cms_encrypted (message))
+            {
+            case 0:
+              newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
+              break;
+            case 1:
+              newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
+              break;
+            }
+          
+        }
+      xfree (smtype);
+      xfree (proto);
+      xfree (ct);
+    }
+  if (!newvalue && opt.enable_smime)
+    newvalue = xstrdup ("IPM.Note.GpgOL");
+
+  return newvalue;
+}
+
+/* Helper for mapi_change_message_class.  Returns the new message
+   class as an allocated string.
+
+   This function is used for the message class
+   "IPM.Note.SMIME.MultipartSigned".  This is an S/MIME message class
+   but smime support is not enabled.  We need to check whether this is
+   actually a PGP/MIME message.  */
+static char *
+change_message_class_ipm_note_smime_multipartsigned (LPMESSAGE message)
+{
+  char *newvalue = NULL;
+  char *ct, *proto;
+
+  ct = mapi_get_message_content_type (message, &proto, NULL);
+  if (!ct)
+    log_debug ("%s:%s: message has no content type", SRCNAME, __func__);
+  else
+    {
+      log_debug ("%s:%s: content type is '%s'", SRCNAME, __func__, ct);
+      if (proto 
+          && !strcmp (ct, "multipart/signed")
+          && !strcmp (proto, "application/pgp-signature"))
+        {
+          newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
+        }
+      xfree (proto);
+      xfree (ct);
+    }
+  
+  return newvalue;
+}
+
+/* Helper for mapi_change_message_class.  Returns the new message
+   class as an allocated string.
+
+   This function is used for the message classes
+   "IPM.Note.Secure.CexSig" and "IPM.Note.Secure.Cexenc" (in the
+   latter case IS_CEXSIG is true).  These are CryptoEx generated
+   signature or encryption messages.  */
+static char *
+change_message_class_ipm_note_secure_cex (LPMESSAGE message, int is_cexenc)
+{
+  char *newvalue = NULL;
+  char *ct, *smtype, *proto;
+  
+  ct = mapi_get_message_content_type (message, &proto, &smtype);
+  if (ct)
+    {
+      log_debug ("%s:%s: content type is '%s'", SRCNAME, __func__, ct);
+      if (smtype)
+        log_debug ("%s:%s:   smime-type is '%s'", SRCNAME, __func__, smtype);
+      if (proto)
+        log_debug ("%s:%s:     protocol is '%s'", SRCNAME, __func__, proto);
+
+      if (smtype)
+        {
+          if (!strcmp (ct, "application/pkcs7-mime")
+              || !strcmp (ct, "application/x-pkcs7-mime"))
+            {
+              if (!strcmp (smtype, "signed-data"))
+                newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
+              else if (!strcmp (smtype, "enveloped-data"))
+                newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
+            }
+        }
+
+      if (!newvalue && proto)
+        {
+          if (!strcmp (ct, "multipart/signed")
+              && (!strcmp (proto, "application/pkcs7-signature")
+                  || !strcmp (proto, "application/x-pkcs7-signature")))
+            {
+              newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
+            }
+          else if (!strcmp (ct, "multipart/signed")
+                   && (!strcmp (proto, "application/pgp-signature")))
+            {
+              newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
+            }
+        }
+      
+      if (!newvalue && !strcmp (ct, "text/plain"))
+        {
+          newvalue = get_msgcls_from_pgp_lines (message);
+        }
+      
+      if (!newvalue)
+        {
+          switch (is_really_cms_encrypted (message))
+            {
+            case 0:
+              newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
+              break;
+            case 1:
+              newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
+              break;
+            }
+        }
+      
+      xfree (smtype);
+      xfree (proto);
+      xfree (ct);
+    }
+  else
+    {
+      log_debug ("%s:%s: message has no content type", SRCNAME, __func__);
+      if (is_cexenc)
+        {
+          switch (is_really_cms_encrypted (message))
+            {
+            case 0:
+              newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
+              break;
+            case 1:
+              newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
+              break;
+            }
+        }
+    }
+
+  if (!newvalue)
+    newvalue = xstrdup ("IPM.Note.GpgOL");
+
+  return newvalue;
+}
+
+
 /* This function checks whether MESSAGE requires processing by us and
    adjusts the message class to our own.  By passing true for
    SYNC_OVERRIDE the actual MAPI message class will be updated to our
@@ -743,108 +1001,11 @@
                        SRCNAME, __func__, s);
       if (!strcmp (s, "IPM.Note"))
         {
-          /* Most message today are of this type.  However a PGP/MIME
-             encrypted message also has this class here.  We need
-             to see whether we can detect such a mail right here and
-             change the message class accordingly. */
-          char *ct, *proto;
-
-          ct = mapi_get_message_content_type (message, &proto, NULL);
-          if (!ct)
-            log_debug ("%s:%s: message has no content type", 
-                       SRCNAME, __func__);
-          else
-            {
-              log_debug ("%s:%s: content type is '%s'", 
-                         SRCNAME, __func__, ct);
-              if (proto)
-                {
-                  log_debug ("%s:%s:     protocol is '%s'", 
-                             SRCNAME, __func__, proto);
-              
-                  if (!strcmp (ct, "multipart/encrypted")
-                      && !strcmp (proto, "application/pgp-encrypted"))
-                    {
-                      newvalue = xstrdup ("IPM.Note.GpgOL.MultipartEncrypted");
-                    }
-                  else if (!strcmp (ct, "multipart/signed")
-                           && !strcmp (proto, "application/pgp-signature"))
-                    {
-                      /* Sometimes we receive a PGP/MIME signed
-                         message with a class IPM.Note.  */
-                      newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
-                    }
-                  xfree (proto);
-                }
-              else if (!strcmp (ct, "text/plain"))
-                {
-                  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);
-            }
+          newvalue = change_message_class_ipm_note (message);
         }
       else if (!strcmp (s, "IPM.Note.SMIME"))
         {
-          /* This is an S/MIME opaque encrypted or signed message.
-             Check what it really is.  Notee that this might even be a
-             PGP/MIME mail. */
-          char *ct, *proto, *smtype;
-
-          ct = mapi_get_message_content_type (message, &proto, &smtype);
-          if (!ct)
-            log_debug ("%s:%s: message has no content type", 
-                       SRCNAME, __func__);
-          else
-            {
-              log_debug ("%s:%s: content type is '%s'", 
-                         SRCNAME, __func__, ct);
-              if (proto 
-                  && !strcmp (ct, "multipart/signed")
-                  && !strcmp (proto, "application/pgp-signature"))
-                {
-                  newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
-                }
-              else if (!opt.enable_smime)
-                ; /* S/MIME not enabled; thus no further checks.  */
-              else if (smtype)
-                {
-                  log_debug ("%s:%s:   smime-type is '%s'", 
-                             SRCNAME, __func__, smtype);
-              
-                  if (!strcmp (ct, "application/pkcs7-mime")
-                      || !strcmp (ct, "application/x-pkcs7-mime"))
-                    {
-                      if (!strcmp (smtype, "signed-data"))
-                        newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
-                      else if (!strcmp (smtype, "enveloped-data"))
-                        newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
-                    }
-                }
-              else
-                {
-                  /* No smime type.  The filename parameter is often
-                     not reliable, thus we better look into the
-                     message to see whetehr it is encrypted and assume
-                     an opaque signed one if not.  */
-                  if (is_really_cms_encrypted (message))
-                    newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
-                  else
-                    newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
-                }
-              xfree (smtype);
-              xfree (proto);
-              xfree (ct);
-            }
-          if (!newvalue && opt.enable_smime)
-            newvalue = xstrdup ("IPM.Note.GpgOL");
+          newvalue = change_message_class_ipm_note_smime (message);
         }
       else if (opt.enable_smime
                && !strncmp (s, "IPM.Note.SMIME", 14) && (!s[14]||s[14] =='.'))
@@ -861,27 +1022,10 @@
       else if (!strcmp (s, "IPM.Note.SMIME.MultipartSigned"))
         {
           /* This is an S/MIME message class but smime support is not
-             enabled.  We need to check whetehr this is actually a
+             enabled.  We need to check whether this is actually a
              PGP/MIME message.  */
-          char *ct, *proto;
-
-          ct = mapi_get_message_content_type (message, &proto, NULL);
-          if (!ct)
-            log_debug ("%s:%s: message has no content type", 
-                       SRCNAME, __func__);
-          else
-            {
-              log_debug ("%s:%s: content type is '%s'", 
-                         SRCNAME, __func__, ct);
-              if (proto 
-                  && !strcmp (ct, "multipart/signed")
-                  && !strcmp (proto, "application/pgp-signature"))
-                {
-                  newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
-                }
-              xfree (proto);
-              xfree (ct);
-            }
+          newvalue = change_message_class_ipm_note_smime_multipartsigned
+            (message);
         }
       else if (opt.enable_smime && sync_override && have_override
                && !strncmp (s, "IPM.Note.GpgOL", 14) && (!s[14]||s[14] =='.'))
@@ -902,76 +1046,11 @@
                && (!strcmp (s, "IPM.Note.Secure.CexSig")
                    || (cexenc = !strcmp (s, "IPM.Note.Secure.CexEnc"))))
         {
-          /* This is a CryptoEx generated signature or encrypted data. */
-          char *ct, *smtype, *proto;
-
-          ct = mapi_get_message_content_type (message, &proto, &smtype);
-          if (!ct)
-            {
-              log_debug ("%s:%s: message has no content type", 
-                         SRCNAME, __func__);
-              if (cexenc)
-                {
-                  if (is_really_cms_encrypted (message))
-                    newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
-                  else
-                    newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
-                }
-            }
-          else
-            {
-              log_debug ("%s:%s: content type is '%s'", 
-                         SRCNAME, __func__, ct);
-              if (smtype)
-               log_debug ("%s:%s:   smime-type is '%s'", 
-                           SRCNAME, __func__, smtype);
-              if (proto)
-                log_debug ("%s:%s:     protocol is '%s'", 
-                           SRCNAME, __func__, proto);
-              if (smtype)
-                {
-                  if (!strcmp (ct, "application/pkcs7-mime")
-                      || !strcmp (ct, "application/x-pkcs7-mime"))
-                    {
-                      if (!strcmp (smtype, "signed-data"))
-                        newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
-                      else if (!strcmp (smtype, "enveloped-data"))
-                        newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
-                    }
-                }
-
-              if (!newvalue && proto)
-                {
-                  if (!strcmp (ct, "multipart/signed")
-                      && (!strcmp (proto, "application/pkcs7-signature")
-                          || !strcmp (proto, "application/x-pkcs7-signature")))
-                    newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
-                  else if (!strcmp (ct, "multipart/signed")
-                           && (!strcmp (proto, "application/pgp-signature")))
-                    newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned");
-                }
-
-              if (!newvalue && !strcmp (ct, "text/plain"))
-                {
-                  newvalue = get_msgcls_from_pgp_lines (message);
-                }
-
-              if (!newvalue)
-                {
-                  if (is_really_cms_encrypted (message))
-                    newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted");
-                  else
-                    newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned");
-                }
-
-              xfree (smtype);
-              xfree (proto);
-              xfree (ct);
-            }
-          if (!newvalue)
-            newvalue = xstrdup ("IPM.Note.GpgOL");
+          newvalue = change_message_class_ipm_note_secure_cex
+            (message, cexenc);
         }
     }
+
   if (!newvalue)
     {
       /* We use our Sig-Status property to mark messages which passed
@@ -2308,7 +2387,7 @@
   if (PROP_TYPE (propval->ulPropTag) != PT_STRING8)
     {
       /* As per rfc822, header lines must be plain ascii, so no need
-         to cope withy unicode etc. */
+         to cope with unicode etc. */
       log_error ("%s:%s: proptag=%#lx not supported\n",
                  SRCNAME, __func__, propval->ulPropTag);
       MAPIFreeBuffer (propval);




More information about the Gnupg-commits mailing list