Skip to content

Latest commit

 

History

History
152 lines (118 loc) · 4.87 KB

FAQ.md

File metadata and controls

152 lines (118 loc) · 4.87 KB

Frequently Asked Questions

How do I get the message body text?

MIME is a tree structure of parts. There are multiparts which contain other parts (even other multiparts). There are message parts which contain messages. And there are leaf-node parts which contain content.

There are a few common message structures:

  1. The message contains only a text/plain or text/html part (easy, just use that).

  2. The message contains a multipart/alternative which will typically look a bit like this:

    multipart/alternative
       text/plain
       text/html
    
  3. Same as above, but the html part is inside a multipart/related so that it can embed images:

    multipart/alternative
       text/plain
       multipart/related
          text/html
          image/jpeg
          image/png
    
  4. The message contains a textual body part as well as some attachments:

    multipart/mixed
       text/plain or text/html
       application/octet-stream
       application/zip
    
  5. the same as above, but with the first part replaced with either #2 or #3. To illustrate:

    multipart/mixed
       multipart/alternative
          text/plain
          text/html
       application/octet-stream
       application/zip
    

    or...

    multipart/mixed
       multipart/alternative
          text/plain
          multipart/related
             text/html
             image/jpeg
             image/png
       application/octet-stream
       application/zip
    

Now, if you don't care about any of that and just want to get the text of the first text/plain or text/html part you can find, that's easy.

Just look for a node that is of type TextPart and then get the Text property value. For example, using LINQ, you could do this:

var body = message.BodyParts.OfType<TextPart> ().FirstOrDefault ();

Now that you've got the body, you can just use body.Text.

How do I decrypt PGP messages that are embedded in the main message text?

Some PGP-enabled mail clients, such as Thunderbird, embed encrypted PGP blurbs within the text/plain body of the message rather than using the PGP/MIME format that MimeKit prefers.

These messages often look something like this:

Return-Path: <[email protected]>
Received: from [127.0.0.1] (hostname.example.com. [201.95.8.17])
    by mx.google.com with ESMTPSA id l67sm26628445yha.8.2014.04.27.13.49.44
    for <[email protected]>
    (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
    Sun, 27 Apr 2014 13:49:44 -0700 (PDT)
Message-ID: <[email protected]>
Date: Sun, 27 Apr 2014 17:49:43 -0300
From: Die-Hard PGP Fan <[email protected]>
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0
MIME-Version: 1.0
To: undisclosed-recipients:;
Subject: Test of inline encrypted PGP blocks
X-Enigmail-Version: 1.6
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Antivirus: avast! (VPS 140427-1, 27/04/2014), Outbound message
X-Antivirus-Status: Clean

-----BEGIN PGP MESSAGE-----
Charset: ISO-8859-1
Version: GnuPG v2.0.22 (MingW32)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

SGFoISBJIGZvb2xlZCB5b3UsIHRoaXMgdGV4dCBpc24ndCBhY3R1YWxseSBlbmNy
eXB0ZWQgd2l0aCBQR1AsCml0J3MgYWN0dWFsbHkgb25seSBiYXNlNjQgZW5jb2Rl
ZCEKCkknbSBqdXN0IHVzaW5nIHRoaXMgYXMgYW4gZXhhbXBsZSwgdGhvdWdoLCBz
byBpdCBkb2Vzbid0IHJlYWxseSBtYXR0ZXIuCgpGb3IgdGhlIHNha2Ugb2YgYXJn
dW1lbnQsIHdlJ2xsIHByZXRlbmQgdGhhdCB0aGlzIGlzIGFjdHVhbGx5IGFuIGVu
Y3J5cHRlZApibHVyYi4gTW1ta2F5PyBUaGFua3MuCg==
-----END PGP MESSAGE-----

To deal with these kinds of messages, I've added a method to OpenPgpContext called GetDecryptedStream which can be used to get the raw decrypted stream.

There are actually 2 variants of this methods:

public Stream GetDecryptedStream (Stream encryptedData, out DigitalSignatureCollection signatures)

and

public Stream GetDecryptedStream (Stream encryptedData)

The first variant is useful in cases where the encrypted PGP blurb is also digitally signed, allowing you to get your hands on the list of digitial signatures in order for you to verify each of them.

To decrypt the content of the message, you'll want to locate the TextPart (in this case, it'll just be message.Body) and then do this:

static Stream DecryptEmbeddedPgp (TextPart text)
{
    using (var memory = new MemoryStream ()) {
        text.ContentObject.DecodeTo (memory);
        memory.Position = 0;

        using (var ctx = new MyGnuPGContext ()) {
            return ctx.GetDecryptedStream (memory);
        }
    }
}

What you do with that decrypted stream is up to you. It's up to you to figure out what the decrypted content is (is it text? a jpeg image? a video?) and how to display it to the user.