Is there a difference between the Outlook .MSG and .OFT file formats? - email

This question is somewhat of a long shot, but I've spent hours on it to no avail. I have some code that generates an email file on a webserver, and allows the user to download that email and open it in Outlook. From here, they can make various manual changes to the email before they send it to a bunch of people.
Right now, I generate a .OFT file, which is basically an email template. What I want to do is generate a .MSG file, which is an actual email. From a binary point of view, it seems these file formats are identical. They have the same Stream IDs and properties and stuff.
My approach was to first create a blank email message in Outlook and then just save it to a file called Base.oft. In my code, I open the document and modify Stream ID __substg1.0_1013001E which is the ID for the HTML email body. I then save the file and write it out to the cilent. This works perfectly.
I tried the same approach with the MSG format. I created a blank email message, saved it as Base.msg, and modify the same Stream ID. If I look at the resulting file, the new body is actually in there and saved. However, if I open the email, the body is still blank.
What's even weirder is if I type in a body in Outlook and save that to the base file, I can see that body under stream 0_1013001E. If I then modify that stream with a different body, I can verify the new body is indeed saved in the file, but if I open the message in Outlook, I see the old, original body. It's as if the email body is stored in a different place in the file for the .MSG format, however I've looked through each stream and cannot find anything else that looks like it could be an email body.
Perhaps .MSG files are encrypted, or their bodies are stored in some proprietary binary format unlike .OFT files? Hopefully someone has some insight on this, as I scoured the Internet and found basically nothing on these formats.
Update:
It seems the .MSG format stores the body in Stream ID __substg1.0_10090102 - Which is encoded in some binary form (not sure what.) If I delete the stream (or set it to a single \0, the file becomes corrupt.

First of all, to find more information on this and related topics, move away from raw substream numbers and google for the corresponding MAPI properties. For example, 1013 is PR_HTML and 1009 is PR_RTF_COMPRESSED. MAPI has ways of synching the body from one format to the other.
See this article on MSDN for a good overview of all content-related MAPI properties (i.e. the different "streams" inside the .MSG file).
To write PR_RTF_COMPRESSED, wrap the stream inside WrapCompressedStream. On the other hand, in your particular situation you might want to avoid the MAPI-dependencies in your code, so maybe you're better off finding the PR_STORE_SUPPORT_MASK and setting the STORE_UNCOMPRESSED_RTF bit. This will allow you to use straight RTF in the PR_RTF_COMPRESSED substream. Or Outlooks fancy html-wrapped-in-rtf, if you are feeling brave.
None of this stuff is for the faint of heart, but seeing how you are already handing raw .MSG substream writing, I'm guessing it would be feasible.

When it comes to the format, there is no difference.
the only difference is that OFT files have CLSID_TemplateMessage ({0006F046-0000-0000-C000-000000000046}) as the storage class (WriteClassStg), while MSG files use CLSID_MailMessage ({00020D0B-0000-0000-C000-000000000046})

Related

Procmail mail to file

i want to configure procmail. Right now i've got code to redirect mails with selected topic from server mail to my mail. It's my code:
:0 c
*Subject.*ExampleTopic
Example#Mail.com
I want to copy mail content to selected .txt file on server. How can i do it?
Your current code saves a copy to a folder named Example#Mail.com. To save to a file with a different name, simply change that string. (To forward each matching message to another email address, the syntax is ! Email#example.com with an exclamation mark as the action "verb".)
The default saving action appends to a flat text file in Berkeley mbox format. This includes both the headers and the body. With a b flag you can save just the email body, but this is still the raw MIME transport format, which is very rarely what you actually want.
:0b
* some condition, perhaps
bodyfile.txt
Procmail regrettably knows nothing about MIME, so if getting a particular body part is what you actually need, you'll probably want to pipe the message to some script which understands MIME and can implement your extraction policy.
:0
* some condition, maybe
| extracttool >>bodyfile.txt
The vague wording of your question implies that you are probably not too familiar with the details of email formatting in general and MIME in particular. You'll probably want to post another question with more detailed requirements once you have a proper idea of what the challenges are. For a start, the source of a message you want to mainpulate might help us help you.

How to append text to a file in Objective C?

I have a form in my app that the user fills out, then the app needs to write what the user entered into a .java file that is then sent to the user. Basically, I'm making a mobile Java IDE. Please help! I need to know how to append text into certain locations in the file. Excuse me if this doesn't make sense, just ask me what part is confusing, I might be able to explain it better.
You are probably a lot better off storing all your text in a database, where you can easily insert new text at any location.
Actually storing the text in a file is problematic - appending is easy, you just open the file, seek to the end, and then write new text. But you really want arbitrary insertion of text which means seeking to that point in the file, reading in the rest of the file, writing out your new data, then writing out the old remainder of the file...
If you store all the text in a database you can organize it to make it easy to insert new text, probably append some useful metadata about the text, and when the user asks to email the file simply write everything you have out to a file in temporary storage and send that (or create the text in memory and send it as NSData).

What is the difference between an `eml` file and an RFC822 email message?

I see these two terms used interchangeably in a lot of context, but some sources say that eml is a file format that originated with Microsoft Outlook.
Is eml the official file suffix of an RFC822 message saved as a flat text file?
There is no official definition of what "eml" means, and different programs use it in different ways. Sometimes people use it to mean RFC822, other times they mean something different. If you mean RFC822 format, say so.

How to read a file from the disk if less than X days old, if older, refetch the html file

I wish to read an html file off of the internet and cache it. Then when I go back, because I'm debugging, I don't want to hammer the servers with the numerous requests I'll need. I don't want to get my IP banned for slamming the server over and over again just because I'm debugging. So my code needs to look something like:
if ((file > days_old) || !(file exists))
fetch html file from internet
save file to disk
else
read it from the disk
Because there will be multiple files, I'll need to include a variable name in the file name so the file is unique and I can easily look it up again.
I just learned Perl this semester and we only learned the basics & a bit of regex, once I get this I should be mostly fine.
Thanks!
Use an existing module:
Cache::Cache
HTTP::Cache::Transparent
If you really want to implement your own, you'll want to look at the If-Modified-Since and ETag HTTP headers to determine when to re-fetch a file, rather than an arbitrary days_old number you suck out of your thumb. You will also have to generate a unique filename, preferably with a hash function, while retaining the original URL to cater for hash collisions.

How can I limit file types in CGI file uploads in Perl?

I am using CGI to allow the user to upload some files. I just want the just to be able to upload .txt or .csv files. If the user uploads file with any other format then I want to be able to put out an error message.
I saw that this can be done by javascript: http://www.codestore.net/store.nsf/unid/DOMM-4Q8H9E
But is there a better way to achieve this? Is there is some functionality in Perl that allows this?
The disclaimer on the site to you link to is important:
Note: This is not entirely foolproof as people can easily change the extension of a file before uploading it, or do some other trickery, as in the case of the "LoveBug" virus.
If you really want to do this right, let the user upload the file, and
then use something like File::MimeInfo::Magic (or file(1), the
UNIX utility) to guess the actual file type. If you don't like the
file type, delete the file and give the user an error message.
I just want the just to be able to upload .txt or .csv files.
Sounds easy, doesn't it? It's not. And then some.
The simple approach is just to test that the file ends in ‘.txt’ or ‘.csv’ before storing it on the filesystem. This should be part of a much more in-depth validation of what the filename is allowed to contain before you let a user-submitted filename anywhere near the filesystem.
Because the rules about what can go in a filename are complex on some platforms (especially Windows) it's usually best to create your own filename independently with a known-good name and extension.
In any case there is no guarantee that the browser will send you a file with a usable name at all, and even if it does there is no guarantee that name will have ‘.txt’ or ‘.csv’ at the end, even if it is a text or CSV file. (Some platforms simply do not use extensions for file typing.)
Whilst you can try to sniff the contents of the file to see what type it might be, this is highly unreliable. For example:
<html>,<body>,</body>,</html>
could be plain text, CSV, HTML, XML, or a variety of other formats. Better to give the user an explicit control to say what file type they're uploading (or use one file upload field per type).
Now here's where it gets really nasty. Say you've accepted the upload and stored it as /data/mygoodfilename.txt, and the web server is correctly serving it as the Content-Type ‘text/plain’. What do you think the browser interprets it as? Plain text? You should be so lucky.
The problem is that browsers (primarily IE) don't trust your Content-Type header, and instead sniff the contents of the file to see if it looks like something else. Serve the above snippet as plain text, and IE will happily treat it as HTML. This can be a huge problem, because HTML can include client-side scripts that will take over the user's access to the site (a cross-site-scripting attack).
At this point you might be tempted to sniff the file on the server-side, for example using the ‘file’ command, to check it doesn't contain ‘<html>’. But this is doomed to failure. The ‘file’ command does not sniff for all the same HTML tags as IE does, and other browsers sniff differently anyway. It's quite easy to prepare a file that ‘file’ will claim is not HTML, but that IE will nevertheless treat as if it is (with security-disaster implications).
Content-sniffing approaches such as ‘file’ will give you only a false sense of security. This is a convenience tool for loose guessing of filetypes and not an effective security measure.
At this point your last desperate possibilities are things like:
serving all user-uploaded files from a separate hostname, so that a script injection attack can't purloin the credentials of your main site;
serving all user-uploaded files through a CGI wrapper, adding the header ‘Content-Disposition: attachment’ so that browsers won't attempt to display them directly;
only accepting uploads from trusted users.
On unix the easiest way is to do an JRockway suggested. If not on unix then your options are limited. You can examine the file extension and you can examine the contents to verify. I'm assuming for you specific case that you only want "* seperated value" text files. So one of the Text::CSV::* modules may be useful in verifying the file is the type you asked for.
Security for this operation is a whole other ball of wax.
try this:
$file_name = "file.txt";
$file_cmd = "file \"$file_name"\";
$file_type = `$file_cmd`;
return 0 unless($file_type =~ /(ASCII|text)/i)