Thursday, October 10, 2013

Server side email attachment filtering

Lets say you have a ticketing system at work.

A ticketing system that does not like receiving large attachments

Where it will either crash on receiving a message that is too large or fail to create a ticket upon receiving said message as well as failing to notify the sender that something went wrong.

Obviously, the best solution would be to get a better ticketing system and avoid the whole thing...

Unfortunately,  You often end up finding out long after the product had been purchased and you are the poor soul left having to "make it work" anyway....

As you will soon see, it is fixable but will require a good amount of duct tape.

Most ticketing systems are setup like this

support@company.com  -->; ticket_system@ticketing.com

If you are lucky, the email server you have at your company is awesome and supports server side filtering natively. If that is the case, then

The other solution (besides buying a different solution) is to remove the attachments before they make it to the ticketing system.



Lets assume, that since you ticketing system sucks, then your companies email server probably also leaves a bit to be desired and there isn't a way to filter out the email attachments.


So, how do you make it work?
Add yet another server into the mix.

I know, hardly ideal for various reasons but I'm sure at this point you are desperate to get it to work.
Then the flow diagram changes to

support@company.com --->; filter@filterserver.com -->;; ticket_system@ticketing.com

You can filter it out using the sieve/pigeonhole language.

I spent sever hours looking, and I wasn't able to find any examples. Heck, I don't think the developers had ever intended sieve to be used in this fashion as what I needed wasn't really documented, but after trial and error I eventually had sucess.


Most systems do not support it (especially hosted email servers) but there is still a few.
Thankfully, favorite email company fastmail  supports sieves.

To jump to the case, here is the bits of code and what they do.

===============
require ["fileinto","envelope",  "reject", "notify"];

#If the email is addressed to support@company.com or emea_support@company.com then keep going, otherwise ignore this message (useful to ignore spam addressed to invalid addresses).

if header :contains ["to", "cc","bcc","resent-to"] ["support@company.com", "emea_support@company.com"] {
#As you can see, there can me multiple values inside brackets and can filter based on any email field


# When the email size is greater than 300k, remove all attachments while  appending (Attachment Removed) to the subject line.

#If it is still too big, truncate the body and bring message down to 100k
#You can also use M for megabytes.

if size :over 300K {
      notify :method "mailto" :options ["ticket_system@ticketing.com","From","Orig","Length", "300k"] :message "$from$ /  $subject$(Attachment Removed) / $text[100k]$";
discard;
#Need discard here, otherwise message will remain in the INBOX on the filter account, where it would eventually exceed your quota and you will be woken up at 3am with a nasty phone-call because the email suddenly stopped flowing

# Also Note discard is immediate permanent deletion, it will not get put into your trash folder. 
#If you want to do that, use fileinto "INBOX.Trash" (or equivalent folder name)
stop; #Stop possessing this message because we don't want to redirect the email twice with the lines below
}

# If it's smaller then that, allow the message to go through like normal without any truncation
redirect "ticket_system@ticketing.com";
stop;
==========
#If you just want to just generate a bounced  message, then do something like this

require ["fileinto","envelope",  "reject", "notify"];

if header :contains ["to", "cc","bcc","resent-to"] ["support@company.com"] {
if size :over 300K {
reject "This message is too big for our system (over 300k).
Please shrink the size of your message and try again";
discard;
stop;
}
redirect "ticket_system@ticketing.com";
}