Broadcom BCM4328 wifi on Ubuntu 9.04 Jaunty
Ubuntu now includes support for this wireless chip in its ‘Restricted Driver Manager’. Sadly the activation silently fails on a fresh install of Ubuntu. The solution? Install b43-fwcutter. Then disable and re-enable the driver in Ubuntu’s Restricted Driver Manager and it will work after a restart.
Comments (11)Processing email feedback loops for fun & profit, part 2
So we know what a feedback loop is and how to use it to identify customers complaining about our mails. The next step is to automate removal of these people.
It turns out many (most?) feedback loop emails you get from ISPs follow the same format. The message is made up of three sections:
- The first section is a generic message from the feedback loop provider, “this is an email abuse report, yadda yadda yadda”.
- The second section is basically useless. It contains some information from the abuse report, but is usually heavily censored.
- The third section is a copy of the original email you sent. Some information is redacted, like the recipient, and the sender address.
To process this we need two pieces of information:
- Which ISP our feedback loop email comes from.
- Who we sent the original email to.
This is relatively easy with Python, which includes the email library module and will do most of the heavy lifting for you.
The ’standard’ feedback loop format is ARF, and is used by (at least) AOL, Comcast and Yahoo. To process an email in this format:
import email message = email.message_from_string(foo) messagefrom = message['From'] # This is how you pull headers out. # Note the keys are not case sensitive messagebody = message.get_payload() # This returns three sections, as described above originalmessage = messagebody[2].get_payload()[0] # This returns the original message. # We need to explicitly get the single payload. originalmessagesender = originalmessage['Return-Path'] # Ta-da! The original sender.
You can then process originalmessagesender as required to retrieve your UID. Once you have that, send a request through to the appropriate interface and you’re done.
Bonus Notes
- Some providers also strip the return path from the original message. We solved this by hand setting the message-id header on all outgoing mail. If you also do that, make sure you set each message-id to a unique value. We use the same string as our sender address, but change the generic ‘@noreply.ourcompany.com’ domain to the real machine involved in sending and also include the output of time.time(), which gives us useful troubleshooting info too.
- The original plan was to process feedback loop messages as they come in by spawning a script for every returned mail. This turned out to be a bad idea because abuse messages seem to come in bursts, making it possible we’d accidentally DOS our own mailserver with tens of python scripts. Now every feedback email will be delivered to a Maildir. We iterate over every message in the Maildir with Python’s mailbox module (which returns an email object as above for each message).
- If your feedback loop is in another format, it’s pretty easy to work out the structure by playing with a sample message in the Python interpreter (IDLE).