From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 1CEE66DE0EE7 for ; Fri, 13 Sep 2019 19:03:54 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.056 X-Spam-Level: X-Spam-Status: No, score=-0.056 tagged_above=-999 required=5 tests=[AWL=-0.055, SPF_PASS=-0.001] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jUNMjbTnL9Bu for ; Fri, 13 Sep 2019 19:03:52 -0700 (PDT) Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) by arlo.cworth.org (Postfix) with ESMTPS id E1A246DE0EDB for ; Fri, 13 Sep 2019 19:03:51 -0700 (PDT) Received: from remotemail by fethera.tethera.net with local (Exim 4.89) (envelope-from ) id 1i8xPi-0007GE-Fl; Fri, 13 Sep 2019 22:03:50 -0400 Received: (nullmailer pid 32002 invoked by uid 1000); Sat, 14 Sep 2019 01:58:27 -0000 From: David Bremner To: Daniel Kahn Gillmor , Notmuch Mail Subject: Re: [PATCH v4 2/4] util/repair: identify and repair "Mixed Up" mangled messages In-Reply-To: <20190909032726.8931-3-dkg@fifthhorseman.net> References: <20190909032726.8931-1-dkg@fifthhorseman.net> <20190909032726.8931-3-dkg@fifthhorseman.net> Date: Fri, 13 Sep 2019 22:58:27 -0300 Message-ID: <871rwj1vwc.fsf@tethera.net> MIME-Version: 1.0 Content-Type: text/plain X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Sep 2019 02:03:54 -0000 Daniel Kahn Gillmor writes: > +/* see > + * https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling-00#section-4.1.1 */ > +static bool > +_notmuch_is_mixed_up_mangled (GMimeObject *part) > +{ > + GMimeMultipart *mpart = NULL; > + GMimeObject *first, *second, *third = NULL; > + char *prelude_string = NULL; > + bool prelude_is_empty; > + > + if (! g_mime_content_type_is_type (g_mime_object_get_content_type (part), > + "multipart", "mixed")) > + return false; Can g_mime_object_get_content_type plausibly fail (and return NULL) here? > + if (! GMIME_IS_MULTIPART (part)) > + return false; I guess this happens if the mime structure does not match the content type declaration? Not sure if this needs a comment or if it's clear enough. > + mpart = GMIME_MULTIPART (part); > + if (mpart == NULL) > + return false; > + if (g_mime_multipart_get_count (mpart) != 3) > + return false; > + first = g_mime_multipart_get_part (mpart, 0); there's a slight cognitive dissonance for me between the zero and one based indexing schemes here. part0, part1, and part2? or maybe an GMimeObject *part[3] > + if (! g_mime_content_type_is_type (g_mime_object_get_content_type (first), > + "text", "plain")) > + return false; > + if (! GMIME_IS_TEXT_PART (first)) > + return false; > + second = g_mime_multipart_get_part (mpart, 1); > + if (! g_mime_content_type_is_type (g_mime_object_get_content_type (second), > + "application", "pgp-encrypted")) > + return false; > + third = g_mime_multipart_get_part (mpart, 2); > + if (! g_mime_content_type_is_type (g_mime_object_get_content_type (third), > + "application", "octet-stream")) > + return false; > + > + /* Is first subpart length 0? */ > + prelude_string = g_mime_text_part_get_text (GMIME_TEXT_PART (first)); > + prelude_is_empty = ! (strcmp ("", prelude_string)); > + g_free (prelude_string); It might make sense to use the EMPTY_STRING macro here, although currently it's only accesible via notmuch-private.h > + if (! prelude_is_empty) > + return false; > + > + /* FIXME: after decoding and stripping whitespace, is second > + * subpart just "Version: 1" ? */ > + > + /* FIXME: can we determine that third subpart is *only* PGP > + * encrypted data? I tried g_mime_part_get_openpgp_data () but > + * found https://github.com/jstedfast/gmime/issues/60 */ > + > + return true; > +} > + > + > +/* see > + * https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling-00#section-4.1.2 */ > +GMimeObject * > +_notmuch_repair_mixed_up_mangled (GMimeObject *part) > +{ > + GMimeMultipart *mpart = NULL, *mpart_ret = NULL; > + GMimeObject *ret = NULL; > + > + if (! _notmuch_is_mixed_up_mangled (part)) > + return NULL; > + mpart = GMIME_MULTIPART (part); > + ret = GMIME_OBJECT (g_mime_multipart_encrypted_new ()); > + if (ret == NULL) > + return NULL; > + mpart_ret = GMIME_MULTIPART (ret); > + if (mpart_ret == NULL) { > + g_object_unref (ret); > + return NULL; > + } > + g_mime_object_set_content_type_parameter (ret, "protocol", "application/pgp-encrypted"); > + > + g_mime_multipart_insert (mpart_ret, 0, g_mime_multipart_get_part (mpart, 1)); > + g_mime_multipart_insert (mpart_ret, 1, g_mime_multipart_get_part (mpart, 2)); > + return ret; > +} > diff --git a/util/repair.h b/util/repair.h > index 9974d693..492f5a20 100644 > --- a/util/repair.h > +++ b/util/repair.h > @@ -25,9 +25,19 @@ extern "C" { > * returned object will only be released when the original part is > * disposed of. > */ > + > GMimeObject * > _notmuch_repair_crypto_payload_skip_legacy_display (GMimeObject *payload); > > +/* Detecting and repairing "Mixed-Up MIME mangling". see > + * https://tools.ietf.org/html/draft-dkg-openpgp-pgpmime-message-mangling-00#section-4.1 > + * If this returns NULL, the message was probably not "Mixed up". If > + * it returns non-NULL, then there is a newly-allocated MIME part that > + * represents the repaired version. The caller is responsible for > + * ensuring that any returned object is freed with g_object_unref. */ > +GMimeObject * > +_notmuch_repair_mixed_up_mangled (GMimeObject *part); > + > #ifdef __cplusplus > } > #endif > -- > 2.23.0 > > _______________________________________________ > notmuch mailing list > notmuch@notmuchmail.org > https://notmuchmail.org/mailman/listinfo/notmuch