Unable to retrieve attachments from a signed mail having ContentType as "application/pkcs7-mime; name=smime.p7m" - jakarta-mail

I am trying to read a digitally signed mail from java code using multipart and mime messaging and fetch the attachments (xml, pdf, txt etc.,) and message details.
My code is working fine for mails having Content-Type as : multipart/signed; protocol="application/x-pkcs7-signature";
But For few mails having Content-Type as : application/pkcs7-mime; smime-type=signed-data; name=smime.p7m it is not fetching the attachments and message details. Can anyone explain what is the difference between both of them and how to resolve it.

I recently came across this issue myself, and although this question is three month old, I leave an answer with my findings, just in case.
Both kinds of messages are instances of S/MIME signed messages as specified in RFC2633 (https://www.rfc-editor.org/rfc/rfc2633).
The multipart/signed; protocol="application/x-pkcs7-signature" indicates a clear-signed message (section 3.4.3.3 of the RFC), meaning you can read the original message content without having S/MIME capabilities in your client code. Hence no problem with these.
The application/pkcs7-mime; smime-type=signed-data; name=smime.p7m indicates an S/MIME signedData email (section 3.4.2) Your client code needs S/MIME capability in order to read the original message (even if you don’t care about the signature).
Easiest way (worked for me) is to use bouncycastle's SMIMESigned class (from the S/MIME API, https://mvnrepository.com/artifact/org.bouncycastle/bcmail-jdk15on), like this:
byte[] content = <the signed data's content as byte[]>;
ByteArrayDataSource dataSource = new ByteArrayDataSource(content,"multipart/signed");
SMIMESigned signedData = new SMIMESigned(new MimeMultipart(dataSource));
MimeBodyPart bodyPart = signedData.getContent();
<you can process the body part as normal from here>

Related

Microsoft graph API --> To see if the message is a reply

I am using the graph API to retrieve the mail from mail folders. For example I got a mail, I will change or edit the subject line and store the conversation id for future use. if I got the reply mail for the same email chain I got different conversation id. How to handle this, I need to find out the reply mail.
"subject": "Test",
"conversationId": "AAQkADU1YWM2MjMyLTVkOGQtNDdiMy05YWM4LTE4NTNlYzg1ZWRiNwAQADofdbq8_JtJkY8M5wnunlU=",
reply msg:
"subject": "Re: Test1",
"conversationId": "AAQkADU1YWM2MjMyLTVkOGQtNDdiMy05YWM4LTE4NTNlYzg1ZWRiNwAQAHu3pWtxNmBFjdfyjYaVGKc=",
I need to find this ts reply message.
I'd suggest you use the In-Reply-To header https://wesmorgan.blogspot.com/2012/07/understanding-email-headers-part-ii.html in that way you can relate multiple replies (to the same replied to message) in a Message chain etc. You can either get the In-Reply-To header by requesting the InternetHeaders https://learn.microsoft.com/en-us/graph/api/resources/internetmessageheader?view=graph-rest-1.0 (this will return all the headers) or you can request the extended property to just get that one property eg
https://graph.microsoft.com/v1.0/users('user#domain.com')/MailFolders('Inbox')/messages/?$select=ReceivedDateTime,Sender,Subject,IsRead,inferenceClassification,InternetMessageId,parentFolderId,hasAttachments,webLink&$Top=10&$expand=SingleValueExtendedProperties($filter=(Id%20eq%20'String%200x1042'))

sending a .rtf file with javaMail

I am trying to get a file with the .rtf extension as an attachment with an email. I cannot seem to get it in my mailbox.
the code I currently use
try
{
Message msg = new MimeMessage(session);
msg.setFrom( ); // this is filled in but hidden for this question
msg.addRecipient();// this is filled in but hidden for this question
msg.setSubject("test email");
msg.setText("body test content");
msg.setSentDate(new Date());
Multipart multipart = new MimeMultipart();
MimeBodyPart messageBodyPart = new MimeBodyPart();
FileDataSource source = new FileDataSource(receiveFile);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.attachFile(backupFile);
messageBodyPart.setFileName("reportFile.rtf");
multipart.addBodyPart(messageBodyPart);
msg.setContent(multipart);
Transport.send(msg);
}
receiveFile is the rtf file in question that needs to be send as an attachement.
Do not bother wtih server settings and such. I have send emails using this code so that works all just fine :). and had success sending .txt or .doc files as well so I know my info is correct. just when I try to send it as reportFile.rtf the mail just does not arrive. and I have tried 2 systems both together (the datahandler + source path and the attachFile path) and both did not really give me what I wanted.
Is a rtf file as attachment possible using javaMail or am I looking in the wrong direction?
After looking at it more closely with my co-worker we figured out that the email I used as sender was interperted as a spam and thus dumped it in the spam folder. now in itself this is not a problem since it was fine for testing. However it seems that if you keep spamming with that address the mail server indeed blocks like a good percentage of the mails i was sending. So this made it hard to debug since it sometimes got through and sometimes did not. the issues has been resolved now.

What is the size limit of email body in messages.send method of Gmail API?

I am using official .net api client to send emails with attachments by messages.send method. When I attach a file of size more than approximately 5mb, I've come to
[JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.]
Newtonsoft.Json.JsonTextReader.ParseValue() +1187
Newtonsoft.Json.JsonTextReader.ReadInternal() +65
Newtonsoft.Json.JsonTextReader.Read() +28
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) +237
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) +783
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) +293
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) +274
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) +57
Google.Apis.Json.NewtonsoftJsonSerializer.Deserialize(String input) in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis.Core\Apis\Json\NewtonsoftJsonSerializer.cs:120
Google.Apis.Services.<DeserializeError>d__8.MoveNext() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\Services\BaseClientService.cs:286
[GoogleApiException: An Error occurred, but the error response could not be deserialized]
Google.Apis.Requests.ClientServiceRequest`1.Execute() in c:\code\google.com\google-api-dotnet-client\default\Tools\Google.Apis.Release\bin\Debug\test\default\Src\GoogleApis\Apis\Requests\ClientServiceRequest.cs:102
I think client use Metadata URI, for metadata-only requests. A am going to try another option: Upload URI, for media upload requests.
It looks like there is a limit on email size that leads to exception of parsing error response in the client library.
So, the first question: is there a size limit?
Second, there is no info about how to use different upload methods via client, do you know any client library documentation?
Update: I hacked that request produced by
var request = gmailService.Users.Messages.Send(message, AccountUserId);
is going to https://www.googleapis.com/gmail/v1/users/me/messages/send. As I supposed it didn't use media upload request.
I ended up with limit on attachments total size. Here is code snippet.
Class level:
public const int MaxAttachmentsSize = 5 * 1024 * 1024;
Method level:
var attachmentsSize = 0;
foreach (var attachment in attachments)
{
attachmentsSize += attachment.Item1;
if (attachmentsSize > MaxAttachmentsSize) break;
mailMessage.Attachments.Add(attachment.Item2);
}
There is limit in MB of whole message. Google API allows you for quite big email but it may get timeout when sending if your service because of connection speed will be doing it too long.
According to this google docs it is 35MB:
google api send docs
For anything (uploading) over a few MB you should definitely use the /upload version of the method, otherwise yes you may run into those size limitations.
In response to the second part of your question...
Second, there is no info about how to use different upload methods via client, do you know any client library documentation?
I did a little poking around in the API, and I see that there is also a method that takes a stream as the 3rd parameter.
services.Users.Messages.Send( body, userId, stream, contentType)
Digging into the source code of that, I see that it seems to use a URL that looks like:
upload/....
I haven't tried it yet, and I don't know (yet) what it wants for a "stream", but this looks like a good possibility for getting a resumable upload with a bigger limit.

How can I send a file, for example "exe", with Telnet?

With smtp, i know the commands: "HELO", "MAIL FROM", "RCPT TO", "QUIT", but i don't know how can i attach one file. Anyone can help me ?
telnet smtp.xxxx.xxxx 25
helo xxxx.xxxx
mail from: yyy#xxx.xxx
rcpt to: yy2#xxx.xxx
data
subject: hi
hello
.
quit
This is not something that can be easily done. You probably want to use a library (ex : in python) that will take care of formatting your email according to your needs.
In very brief :
Sending an attachement requires the email to be formatted according to the MIME RFC
A MIME formatted message will use some delimiters to separate the different parts of the message (ex : a plain text part, an HTML part, an attachment part, etc...)
Each MIME part will be prefixed by a header detailing the part content
an attachment part will be identified by a "Content-disposition" header, as detailed in RFC 2183.
The representation of your file will have to be specified using the "Content-Transfer-Encoding" header, described in RFC 2045. A common way to encode files for mail transfer is base64.
If you want to get an idea of how complex it is to generate an email with a valid attachment, you can use your email client to check the source of an email with an attachment (most email clients have this feature). That should eventually convince you to avoid doing this manually :)

java mail attachments getting corrupted

This is my code for attaching the files to the mail:
Multipart mp=new MimeMultipart("mixed");
BodyPart mbody=new MimeBodyPart();
mbody.setHeader("Content-Type", "text/html; charset=us-ascii");
mbody.setHeader("Content-Transfer-Encoding","7bit");
mbody.setContent(content2, "text/html");
mp.addBodyPart(mbody);
for(File file:f){
BodyPart mbody2=new MimeBodyPart();
DataSource ds=new FileDataSource(file.getAbsolutePath());
mbody2.setDataHandler(new DataHandler(ds));
mbody2.setFileName(ds.getName());
mbody2.setHeader("Content-Type", "multipart/mixed");
mbody2.setHeader("Content-Transfer-Encoding", "base64");
mp.addBodyPart(mbody2);
}
m.setContent(mp);
content2 is the html content I am embedding in the E-mail, and I am adding files from an arraylist f.
The problem here is that although the files get attached and I receive the E-mail fine, I am unable to open the attachments because the data is corrupt. This happens for all the files I've tried to attach like jpegs, pdfs, spreadsheets, word docs and txt files.
I read here: https://community.oracle.com/thread/1589120 that this could happen because JavaMail uses encoding that messes up the binary data of the file and adding mbody2.setHeader("Content-Transfer-Encoding", "base64"); should fix the problem but that doesn't work for me.
Any ideas on what could be wrong?
Thanks
Time for some debugging...
First, remove all of the setHeader calls; some of them are wrong and none of them should be necessary.
Next, determine if the problem is on the sending end or the receiving end. Try multiple mail readers to see if they all have problems with the attachments.
Try sending plain text attachments. Are they also corrupted?
Post the protocol trace showing what happens when you send a simple message with a simple attachment that fails, so we can see if the message is being constructed correctly.
What version of JavaMail are you using?
What mail reader are you using to view the attachments?

Resources