index: repair "Mixed Up" messages before indexing.
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Tue, 28 May 2019 18:42:26 +0000 (14:42 -0400)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Sun, 15 Sep 2019 23:07:06 +0000 (19:07 -0400)
When encountering a message that has been mangled in the "mixed up"
way by an intermediate MTA, notmuch should instead repair it and index
the repaired form.

When it does this, it also associates the index.repaired=mixedup
property with the message.  If a problem is found with this repair
process, or an improved repair process is proposed later, this should
make it easy for people to reindex the relevant message.  The property
will also hopefully make it easier to diagnose this particular problem
in the future.

Signed-off-by: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
doc/man7/notmuch-properties.rst
lib/index.cc
test/T351-pgpmime-mangling.sh

index e2db2ef505a39edf60f712261fbdeab21b9ef43b..a7d91d674a89f92e37989e6bb1ca3846839360c2 100644 (file)
@@ -127,6 +127,12 @@ of its normal activity.
     found in that message, since it was able to index the built-in
     protected headers directly.
 
+    ``index.repaired=mixedup`` indicates the repair of a "Mixed Up"
+    encrypted PGP/MIME message, a mangling typically produced by
+    Microsoft's Exchange MTA.  See
+    https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling
+    for more information.
+
 SEE ALSO
 ========
 
index 1301d78a045a09d1272cbf9c81f5b4022b3ea94d..158ba5cff96d1c98cbfcbe0ecd8903f018fbcda2 100644 (file)
@@ -387,11 +387,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);
@@ -444,7 +453,7 @@ _index_mime_part (notmuch_message_t *message,
            }
            _index_mime_part (message, indexopts, toindex, msg_crypto);
        }
-       return;
+       goto DONE;
     }
 
     if (GMIME_IS_MESSAGE_PART (part)) {
@@ -454,14 +463,14 @@ _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_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);
@@ -475,7 +484,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 ();
@@ -521,6 +530,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
index f65b8a24137a8eac9f00b76252c3ffca668c0966..4555f9375bac3aac8f7204bd4f1846f268849094 100755 (executable)
@@ -21,7 +21,6 @@ test_json_nodes <<<"$output" \
                 'body:["original"]'"$bodytext"
 
 test_begin_subtest "repaired 'Mixed-up' messages can be found with index.repaired=mixedup"
-test_subtest_known_broken
 output=$(notmuch search --output=messages property:index.repaired=mixedup)
 test_expect_equal "$output" id:mixed-up@mangling.notmuchmail.org
 
@@ -29,7 +28,6 @@ test_begin_subtest "index cleartext of 'Mixed-Up' mangled PGP/MIME message"
 test_expect_success 'notmuch reindex --decrypt=true id:mixed-up@mangling.notmuchmail.org'
 
 test_begin_subtest "search cleartext of 'Mixed-Up' mangled PGP/MIME message"
-test_subtest_known_broken
 output=$(notmuch search --output=messages body:password)
 test_expect_equal "$output" id:mixed-up@mangling.notmuchmail.org