I fetched emails from gmail server using pop3 with enough_email package. Everything works as expected until I updated the flow like fetch emails which is encrypted by PGP encryption. I already achieved the decryption part of email using OpenPGP package which gives String in this form
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="000000000000da67ad05d5c5dfba"
--000000000000da67ad05d5c5dfba
Content-Type: text/plain; charset="UTF-8"
test 3
--000000000000da67ad05d5c5dfba
Content-Type: text/html; charset="UTF-8"
<div dir="ltr">test 3</div>
--000000000000da67ad05d5c5dfba--
now I am trying to create mimeMessage object from the string so I can parse it using decodeTextPlainPart function. Already tried to create mimeMessage object by using MimeMessage.parseFromText function but it's not working as expected, when ever I try to get plain text using decodeTextPlainPart function from my created mimeMessage object it returns the same thing which I provided to MimeMessage.parseFromText function.
Did I miss something or followed the wrong approach?
OpenPGP.decrypt function return string with \n as line separator but MimeMessage.parseFromText works with \r\n, when I replace all \n with \r\n in string then try to create mimeMessage object from the string I get the expected result.
Related
How do I in Mimekit send an email having the html body base64 encoded?
In code I first create the entire body as a MimeEnitity including attachments using the BodyBuilder. Then I create the MimeMessage to be sent having the body.
The first thing you'll need to do is to locate the HTML body part.
A quick hack might look something like this:
var htmlBody = message.BodyParts.OfType<TextPart> (x => x.IsHtml).FirstOrDefault ();
Then you'll need to set the Content-Transfer-Encoding:
htmlBody.ContentTransferEncoding = ContentEncoding.Base64;
That's it.
What I am trying to achieve:
send a signed, unencrypted email using a smart card token through a Python script
What I've tried so far:
Have a look on an incoming email signed with same corporate smart card system. It is a multipart email with an attached signature headers like the following:
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Sign a text piece using PyKCS11, that is, for a text string and smart card pin code provided the function returns some bytecode.
Study a S/MIME example from M2Crypto though it's PCKS7 where I find code like the following:
s = SMIME.SMIME()
s.load_key('signer_key.pem', 'signer.pem')
p7 = s.sign(buf, SMIME.PKCS7_DETACHED)
..
s.write(out, p7, buf)
What I see so far is:
SMIME implementation I've found works with PKCS7 object (p7 is not a string as I thought initially);
Signed emails contain x-pkcs7-signature
Does this mean, the data I get from the PyKCS11 module in this case is not some sort of "pkcs11" signature and I have just to wrap it up as a PCKS7 object either override the SMIME.write() method?
Or, the whole setup might be a wrong way?
There are a number of good examples of adding attachments from file, but I was wondering if I could do it in a similar way to the way AlternateView.CreateAlternateViewFromString works.
I am separately using IMAP to get the body_text and body_headers of an email from one address and then wish to send it from another (via SMTP) with some changes made, but the attachment added as faithfully as possible. I am using MailMessage and SmtpClient ( System.Net & System.Net.Mail )
I have written code to extract MIME parts from BODY[TEXT] by their "Content-Type:" tag and happily add plain text the html views this way. I have the attachment in the MIME too (see example below) so it seems like I should be able to easily add the attachment directly from the string I can extract from the MIME with "Content-Type: application/octet-stream". At present, I am only interested in it working with application/octet-stream.
I have this available in parts of my code as a string containing either:
Content-Type: application/octet-stream; name="test_file.abc"
Content-Disposition: attachment; filename="test_file.abc"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_j7datrbn0
YWJjIGZpbGU=
Or
Content-Disposition: attachment; filename="test_file.abc"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_j7datrbn0
YWJjIGZpbGU=
From example:
* 53 FETCH (BODY[TEXT] {614}
--001a1140ae52fcc4690558c101ec
Content-Type: multipart/alternative; boundary="001a1140ae52fcc4630558c101ea"
--001a1140ae52fcc4630558c101ea
Content-Type: text/plain; charset="UTF-8"
Blah blah
--001a1140ae52fcc4630558c101ea
Content-Type: text/html; charset="UTF-8"
<div dir="ltr">Blah blah</div>
--001a1140ae52fcc4630558c101ea--
--001a1140ae52fcc4690558c101ec
Content-Type: application/octet-stream; name="test_file.abc"
Content-Disposition: attachment; filename="test_file.abc"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_j7datrbn0
YWJjIGZpbGU=
--001a1140ae52fcc4690558c101ec--
)
$ OK Success
All of the other aspects of my code work, but is there an easy way to directly add the attachment from the MIME data I have. I am not using MimeKit or any libraries other than standard VS ones.
Thank you for reading this long question.
Not really what I wanted to do, but I achieved what I needed as follows:
string name = find_item_by_key(attachment_content, "filename"); // looks for key="value" and returns value
string attachment_base64 = attachment_content.Substring(attachment_content.LastIndexOf("\r\n\r\n"));
attachment_base64 = attachment_base64.Trim('\r', '\n');
byte[] attachment_bytes = Convert.FromBase64String(attachment_base64);
Attachment att = new Attachment(new System.IO.MemoryStream(attachment_bytes), name);
mail.Attachments.Add(att);
Lots of pointless conversions going on, since the data is already Base64 and mail.Attachments.Add will no doubt be converting it back again.
When sending emails using the Gmail API, it places hard line breaks in the body at around 78 characters per line. A similar question about this can be found here.
How can I make this stop? I simply want to send plaintext emails through the API without line breaks. The current formatting looks terrible, especially on mobile clients (tested on Gmail and iOS Mail apps).
I've tried the following headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Am I missing anything?
EDIT: As per Mr.Rebot's suggestion, I've also tried this with no luck:
Content-Type: mixed/alternative
EDIT 2: Here's the exact format of the message I'm sending (attempted with and without the quoted-printable header:
From: Example Account <example1#example.com>
To: <example2#example.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Subject: This is a test!
Date: Tue, 18 Oct 2016 10:46:57 -GMT-07:00
Here is a long test message that will probably cause some words to wrap in strange places.
I take this full message and Base64-encode it, then POST it to /gmail/v1/users/{my_account}/drafts/send?fields=id with the following JSON body:
{
"id": MSG_ID,
"message": {
"raw": BASE64_DATA
}
}
Are you running the content through a quoted printable encoder and sending the encoded content value along with the header or expecting the API to encode it for you?
Per wikipedia it seems like if you add soft line breaks with = less than 76 characters apart as the last character on arbitrary lines, they should get decoded out of the result restoring your original text.
UPDATE
Try sending with this content whose message has been quoted-printable encoded (base64 it):
From: Example Account <example1#example.com>
To: <example2#example.com>
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Subject: This is a test!
Date: Tue, 18 Oct 2016 10:46:57 -GMT-07:00
Here is a long test message that will probably cause some words to wrap in =
strange places.
I'm assuming you have a function similar to this:
1. def create_message(sender, to, cc, subject, message_body):
2. message = MIMEText(message_body, 'html')
3. message['to'] = to
4. message['from'] = sender
5. message['subject'] = subject
6. message['cc'] = cc
7. return {'raw': base64.urlsafe_b64encode(message.as_string())}
The one trick that finally worked for me, after all the attempts to modify the header values and payload dict (which is a member of the message object), was to set (line 2):
message = MIMEText(message_body, 'html') <-- add the 'html' as the second parameter of the MIMEText object constructor
The default code supplied by Google for their gmail API only tells you how to send plain text emails, but they hide how they're doing that.
ala...
message = MIMEText(message_body)
I had to look up the python class email.mime.text.MIMEText object.
That's where you'll see this definition of the constructor for the MIMEText object:
class email.mime.text.MIMEText(_text[, _subtype[, _charset]])
We want to explicitly pass it a value to the _subtype. In this case, we want to pass: 'html' as the _subtype.
Now, you won't have anymore unexpected word wrapping applied to your messages by Google, or the Python mime.text.MIMEText object
This exact issue made me crazy for a good couple of hours, and no solution I could find made any difference.
So if anyone else ends up frustrated here, I'd thought I'd just post my "solution".
Turn your text (what's going to be the body of the email) into simple HTML. I wrapped every paragraph in a simple <p>, and added line-breaks (<br>) where needed (e.g. my signature).
Then, per Andrew's answer, I attached the message body as MIMEText(message_text, _subtype="html"). The plain-text is still not correct AFAIK, but it works and I don't think there's a single actively used email-client out there that doesn't render HTML anymore.
How to extract the text content part of an email using the VMIME lib? I use the following code:
vmime::ref <vmime::body> body = Msg -> getBody();
vmime::ref <const vmime::contentHandler> cts = body -> getContents();
cts -> extract(out);
However, the content printed out is the whole body part of MIME structure of the email, including boundary and parameter settings.
--001a11c2e29cfe6d9f04e8b9a834
Content-Type: text/plain; charset=ISO-8859-1
test1
--001a11c2e29cfe6d9f04e8b9a834
Content-Type: text/html; charset=ISO-8859-1
<div dir="ltr"><br clear="all"><div>test1</div>
</div>
--001a11c2e29cfe6d9f04e8b9a834--
What I need is just the text content. However, I cannot find any API to extract just the text content.
What I need:
test1
I have been stuck for 3 days. Could anyone help???
You should use vmime::messageParser object to parse your message. This way, you will get the text contents via the vmime::textPart objects (use getTextPartList() method on messageParser).
Vincent