]> git.notmuchmail.org Git - notmuch/blobdiff - mime-node.c
status: add print_status_gzbytes
[notmuch] / mime-node.c
index 599d3b65e4176598f3376ba0eaf9cbdfd5c32533..ff6805bf020998e33c45ce5657cf93f79b5a647b 100644 (file)
@@ -36,6 +36,9 @@ typedef struct mime_node_context {
     GMimeMessage *mime_message;
     _notmuch_message_crypto_t *msg_crypto;
 
+    /* repaired/unmangled parts that will need to be cleaned up */
+    GSList *repaired_parts;
+
     /* Context provided by the caller. */
     _notmuch_crypto_t *crypto;
 } mime_node_context_t;
@@ -52,9 +55,21 @@ _mime_node_context_free (mime_node_context_t *res)
     if (res->stream)
        g_object_unref (res->stream);
 
+    if (res->repaired_parts)
+       g_slist_free_full (res->repaired_parts, g_object_unref);
+
     return 0;
 }
 
+/* keep track of objects that need to be destroyed when the mime node
+ * context goes away. */
+static void
+_mime_node_context_track_repaired_part (mime_node_context_t *ctx, GMimeObject *part)
+{
+    if (part)
+       ctx->repaired_parts = g_slist_prepend (ctx->repaired_parts, part);
+}
+
 const _notmuch_message_crypto_t *
 mime_node_get_message_crypto_status (mime_node_t *node)
 {
@@ -177,6 +192,26 @@ set_signature_list_destructor (mime_node_t *node)
     }
 }
 
+/* Unwrapped MIME part destructor */
+static int
+_unwrapped_child_free (GMimeObject **proxy)
+{
+    g_object_unref (*proxy);
+    return 0;
+}
+
+/* Set up unwrapped MIME part destructor */
+static void
+set_unwrapped_child_destructor (mime_node_t *node)
+{
+    GMimeObject **proxy = talloc (node, GMimeObject *);
+
+    if (proxy) {
+       *proxy = node->unwrapped_child;
+       talloc_set_destructor (proxy, _unwrapped_child_free);
+    }
+}
+
 /* Verify a signed mime node */
 static void
 node_verify (mime_node_t *node, GMimeObject *part)
@@ -186,7 +221,7 @@ node_verify (mime_node_t *node, GMimeObject *part)
 
     node->verify_attempted = true;
     node->sig_list = g_mime_multipart_signed_verify (
-       GMIME_MULTIPART_SIGNED (part), GMIME_ENCRYPT_NONE, &err);
+       GMIME_MULTIPART_SIGNED (part), GMIME_VERIFY_NONE, &err);
 
     if (node->sig_list)
        set_signature_list_destructor (node);
@@ -212,19 +247,21 @@ node_decrypt_and_verify (mime_node_t *node, GMimeObject *part)
     GMimeMultipartEncrypted *encrypteddata = GMIME_MULTIPART_ENCRYPTED (part);
     notmuch_message_t *message = NULL;
 
-    if (! node->decrypted_child) {
+    if (! node->unwrapped_child) {
        for (mime_node_t *parent = node; parent; parent = parent->parent)
            if (parent->envelope_file) {
                message = parent->envelope_file;
                break;
            }
 
-       node->decrypted_child = _notmuch_crypto_decrypt (&node->decrypt_attempted,
+       node->unwrapped_child = _notmuch_crypto_decrypt (&node->decrypt_attempted,
                                                         node->ctx->crypto->decrypt,
                                                         message,
                                                         encrypteddata, &decrypt_result, &err);
+       if (node->unwrapped_child)
+           set_unwrapped_child_destructor (node);
     }
-    if (! node->decrypted_child) {
+    if (! node->unwrapped_child) {
        fprintf (stderr, "Failed to decrypt part: %s\n",
                 err ? err->message : "no error explanation given");
        goto DONE;
@@ -298,6 +335,13 @@ _mime_node_set_up_part (mime_node_t *node, GMimeObject *part, int numchild)
        node->part = part;
        node->nchildren = 0;
     } else if (GMIME_IS_MULTIPART (part)) {
+       GMimeObject *repaired_part = _notmuch_repair_mixed_up_mangled (part);
+       if (repaired_part) {
+           /* This was likely "Mixed Up" in transit!  We replace it
+            * with the more likely-to-be-correct variant. */
+           _mime_node_context_track_repaired_part (node->ctx, repaired_part);
+           part = repaired_part;
+       }
        node->part = part;
        node->nchildren = g_mime_multipart_get_count (GMIME_MULTIPART (part));
     } else if (GMIME_IS_MESSAGE_PART (part)) {
@@ -358,8 +402,8 @@ mime_node_child (mime_node_t *parent, int child)
        return NULL;
 
     if (GMIME_IS_MULTIPART (parent->part)) {
-       if (child == GMIME_MULTIPART_ENCRYPTED_CONTENT && parent->decrypted_child)
-           sub = parent->decrypted_child;
+       if (child == GMIME_MULTIPART_ENCRYPTED_CONTENT && parent->unwrapped_child)
+           sub = parent->unwrapped_child;
        else
            sub = g_mime_multipart_get_part (
                GMIME_MULTIPART (parent->part), child);