]> git.notmuchmail.org Git - notmuch/blobdiff - lib/index.cc
smime: Index cleartext of envelopedData when requested
[notmuch] / lib / index.cc
index db3dd56854d1edb8d81280c4863543ef1a28566d..826aa341d678b2345962cb944becee6b8b50f202 100644 (file)
@@ -369,9 +369,15 @@ _index_content_type (notmuch_message_t *message, GMimeObject *part)
 
 static void
 _index_encrypted_mime_part (notmuch_message_t *message, notmuch_indexopts_t *indexopts,
-                           GMimeMultipartEncrypted *part,
+                           GMimeObject *part,
                            _notmuch_message_crypto_t *msg_crypto);
 
+static void
+_index_pkcs7_part (notmuch_message_t *message,
+                  notmuch_indexopts_t *indexopts,
+                  GMimeObject *part,
+                  _notmuch_message_crypto_t *msg_crypto);
+
 /* Callback to generate terms for each mime part of a message. */
 static void
 _index_mime_part (notmuch_message_t *message,
@@ -387,11 +393,20 @@ _index_mime_part (notmuch_message_t *message,
     GMimeContentType *content_type;
     char *body;
     const char *charset;
+    GMimeObject *repaired_part = NULL;
 
     if (! part) {
        _notmuch_database_log (notmuch_message_get_database (message),
                               "Warning: Not indexing empty mime part.\n");
-       return;
+       goto DONE;
+    }
+
+    repaired_part = _notmuch_repair_mixed_up_mangled (part);
+    if (repaired_part) {
+       /* This was likely "Mixed Up" in transit!  We will instead use
+        * the more likely-to-be-correct variant. */
+       notmuch_message_add_property (message, "index.repaired", "mixedup");
+       part = repaired_part;
     }
 
     _index_content_type (message, part);
@@ -407,7 +422,6 @@ _index_mime_part (notmuch_message_t *message,
            _notmuch_message_add_term (message, "tag", "encrypted");
 
        for (i = 0; i < g_mime_multipart_get_count (multipart); i++) {
-           notmuch_status_t status;
            GMimeObject *child;
            if (GMIME_IS_MULTIPART_SIGNED (multipart)) {
                /* Don't index the signature, but index its content type. */
@@ -425,7 +439,7 @@ _index_mime_part (notmuch_message_t *message,
                                     g_mime_multipart_get_part (multipart, i));
                if (i == GMIME_MULTIPART_ENCRYPTED_CONTENT) {
                    _index_encrypted_mime_part (message, indexopts,
-                                               GMIME_MULTIPART_ENCRYPTED (part),
+                                               part,
                                                msg_crypto);
                } else {
                    if (i != GMIME_MULTIPART_ENCRYPTED_VERSION) {
@@ -436,14 +450,16 @@ _index_mime_part (notmuch_message_t *message,
                continue;
            }
            child = g_mime_multipart_get_part (multipart, i);
-           status = _notmuch_message_crypto_potential_payload (msg_crypto, child, part, i);
-           if (status)
-               _notmuch_database_log (notmuch_message_get_database (message),
-                                      "Warning: failed to mark the potential cryptographic payload (%s).\n",
-                                      notmuch_status_to_string (status));
-           _index_mime_part (message, indexopts, child, msg_crypto);
+           GMimeObject *toindex = child;
+           if (_notmuch_message_crypto_potential_payload (msg_crypto, child, part, i) &&
+               msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+               toindex = _notmuch_repair_crypto_payload_skip_legacy_display (child);
+               if (toindex != child)
+                   notmuch_message_add_property (message, "index.repaired", "skip-protected-headers-legacy-display");
+           }
+           _index_mime_part (message, indexopts, toindex, msg_crypto);
        }
-       return;
+       goto DONE;
     }
 
     if (GMIME_IS_MESSAGE_PART (part)) {
@@ -453,14 +469,19 @@ _index_mime_part (notmuch_message_t *message,
 
        _index_mime_part (message, indexopts, g_mime_message_get_mime_part (mime_message), msg_crypto);
 
-       return;
+       goto DONE;
+    }
+
+    if (GMIME_IS_APPLICATION_PKCS7_MIME (part)) {
+       _index_pkcs7_part (message, indexopts, part, msg_crypto);
+       goto DONE;
     }
 
     if (! (GMIME_IS_PART (part))) {
        _notmuch_database_log (notmuch_message_get_database (message),
                               "Warning: Not indexing unknown mime part: %s.\n",
                               g_type_name (G_OBJECT_TYPE (part)));
-       return;
+       goto DONE;
     }
 
     disposition = g_mime_object_get_content_disposition (part);
@@ -474,7 +495,7 @@ _index_mime_part (notmuch_message_t *message,
 
        /* XXX: Would be nice to call out to something here to parse
         * the attachment into text and then index that. */
-       return;
+       goto DONE;
     }
 
     byte_array = g_byte_array_new ();
@@ -520,6 +541,9 @@ _index_mime_part (notmuch_message_t *message,
 
        free (body);
     }
+  DONE:
+    if (repaired_part)
+       g_object_unref (repaired_part);
 }
 
 /* descend (if desired) into the cleartext part of an encrypted MIME
@@ -527,7 +551,7 @@ _index_mime_part (notmuch_message_t *message,
 static void
 _index_encrypted_mime_part (notmuch_message_t *message,
                            notmuch_indexopts_t *indexopts,
-                           GMimeMultipartEncrypted *encrypted_data,
+                           GMimeObject *encrypted_data,
                            _notmuch_message_crypto_t *msg_crypto)
 {
     notmuch_status_t status;
@@ -578,8 +602,14 @@ _index_encrypted_mime_part (notmuch_message_t *message,
        }
        g_object_unref (decrypt_result);
     }
-    status = _notmuch_message_crypto_potential_payload (msg_crypto, clear, GMIME_OBJECT (encrypted_data), GMIME_MULTIPART_ENCRYPTED_CONTENT);
-    _index_mime_part (message, indexopts, clear, msg_crypto);
+    GMimeObject *toindex = clear;
+    if (_notmuch_message_crypto_potential_payload (msg_crypto, clear, encrypted_data, GMIME_MULTIPART_ENCRYPTED_CONTENT) &&
+       msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+       toindex = _notmuch_repair_crypto_payload_skip_legacy_display (clear);
+       if (toindex != clear)
+           notmuch_message_add_property (message, "index.repaired", "skip-protected-headers-legacy-display");
+    }
+    _index_mime_part (message, indexopts, toindex, msg_crypto);
     g_object_unref (clear);
 
     status = notmuch_message_add_property (message, "index.decryption", "success");
@@ -589,6 +619,57 @@ _index_encrypted_mime_part (notmuch_message_t *message,
 
 }
 
+static void
+_index_pkcs7_part (notmuch_message_t *message,
+                  notmuch_indexopts_t *indexopts,
+                  GMimeObject *part,
+                  _notmuch_message_crypto_t *msg_crypto)
+{
+    GMimeApplicationPkcs7Mime *pkcs7;
+    GMimeSecureMimeType p7type;
+    GMimeObject *mimeobj = NULL;
+    GMimeSignatureList *sigs = NULL;
+    GError *err = NULL;
+    notmuch_database_t *notmuch = NULL;
+
+    pkcs7 = GMIME_APPLICATION_PKCS7_MIME (part);
+    p7type = g_mime_application_pkcs7_mime_get_smime_type (pkcs7);
+    notmuch = notmuch_message_get_database (message);
+    _index_content_type (message, part);
+
+    if (p7type == GMIME_SECURE_MIME_TYPE_SIGNED_DATA) {
+       sigs = g_mime_application_pkcs7_mime_verify (pkcs7, GMIME_VERIFY_NONE, &mimeobj, &err);
+       if (sigs == NULL) {
+           _notmuch_database_log (notmuch, "Failed to verify PKCS#7 SignedData during indexing. (%d:%d) [%s]\n",
+                                  err->domain, err->code, err->message);
+           g_error_free (err);
+           goto DONE;
+       }
+       _notmuch_message_add_term (message, "tag", "signed");
+       GMimeObject *toindex = mimeobj;
+       if (_notmuch_message_crypto_potential_payload (msg_crypto, mimeobj, part, 0) &&
+           msg_crypto->decryption_status == NOTMUCH_MESSAGE_DECRYPTED_FULL) {
+           toindex = _notmuch_repair_crypto_payload_skip_legacy_display (mimeobj);
+           if (toindex != mimeobj)
+               notmuch_message_add_property (message, "index.repaired", "skip-protected-headers-legacy-display");
+       }
+       _index_mime_part (message, indexopts, toindex, msg_crypto);
+    } else if (p7type == GMIME_SECURE_MIME_TYPE_ENVELOPED_DATA) {
+       _notmuch_message_add_term (message, "tag", "encrypted");
+       _index_encrypted_mime_part (message, indexopts,
+                                   part,
+                                   msg_crypto);
+    } else {
+       _notmuch_database_log (notmuch, "Cannot currently handle PKCS#7 smime-type '%s'\n",
+                              g_mime_object_get_content_type_parameter (part, "smime-type"));
+    }
+ DONE:
+    if (mimeobj)
+       g_object_unref (mimeobj);
+    if (sigs)
+       g_object_unref (sigs);
+}
+
 static notmuch_status_t
 _notmuch_message_index_user_headers (notmuch_message_t *message, GMimeMessage *mime_message)
 {