Monthly Archives: March 2014

Late nights in London

I read with interest Adrian Kennard’s blog post about late nights in London. If he thinks he’s got it bad, he should try living in Oxford – which is, as I once remarked, “just far enough from London to be annoying”.

For sure, you might think, as a resident of Oxford, that you can dash down to London, see a play, and be home and tucked up in time to go to work in the morning. But can you? Almost invariably, the last fast train back from Paddington turns out to be just too early to be useful. And the last slow train takes the best part of 2 hours. You know you’re out too late when the conductor announces “this is Radley, but the platform has no lights, so don’t break your neck as you step off”. Incidentally, Paddington is probably not the place in London you wanted to be, so add 30 minutes on the tube to your calculations. Oh, and it stops far too early to be useful as well.

In theory, the Oxford Tube and the Oxford Express ought to be solutions to this problem – they run 24 hours, and they terminate slightly closer to my Jericho HQ than the railway station. In practice, I’ve lost count of the number of times I’ve been stood on Buckingham Palace Road or Baker Street waiting in vain for the scheduled coach to turn up. Even late at night, they take distressingly close to 90 minutes door to door, so not much better than the train – and early in the evening, the rush hour makes them too unpredictable.

The closest to a good solution I’ve found is the train down and the coach back, but the ticket prices don’t make that very economic.

There is a solution, if somewhat radical, which an increasingly large number of my friends have been trying lately – namely, moving to London – but I can’t bring myself to go to such lengths. Yet.

Blocking executable files (even buried inside ZIPs) in Exim

One of the handful of family members I host e-mail for had a narrow escape the other day, just about managing to avoid opening an .exe file buried inside a ZIP file attached to an e-mail purporting to be from Amazon.

The quality of some fake e-mails sloshing around these days is very, very good, and it seemed in this case that even the full might of SpamAssassin and ClamAV (with unofficial malware signatures) hadn’t sufficed to stop this one getting to the user’s inbox.

Spurred on by the thought of how long it might have taken me to disinfect their Windows box if they’d opened the .exe, I decided to take more drastic measures and block attachments containing .exes on the server.

Plenty of recipes for doing this are to be found on the net. The really nice bit for me, though, was the chance to break out Eximunit and do some test-driven sysadmin:

from eximunit import EximTestCase

from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders

EXE_REJECT_MSG = """Executable attachments are not accepted. Contact postmaster if you have a
legitimate reason to send such files."""

ZIP_EXE_REJECT_MSG = """Executable attachments are not accepted, even inside ZIP files. Contact
postmaster if you have a legitimate reason to send such files."""

class ExeTests(EximTestCase):
    """Tests for .exe rejection"""

    def setUp(self):
        # Sets the default IP for sesions to be faked from
        self.setDefaultFromIP("10.0.0.1")

    def testDavidDomainRejectsExe(self):
        self.newSession().mailFrom('evil-spammer@example.com')\
                         .rcptTo('victim@dnorth.net').assertDataRejected(self.messageWithAttachment('test.exe'), EXE_REJECT_MSG)

    def testDavidDomainRejectsExeZip(self):
        self.newSession().mailFrom('evil-spammer@example.com')\
                         .rcptTo('victim@dnorth.net').assertDataRejected(self.messageWithAttachment('test.zip'), ZIP_EXE_REJECT_MSG)

    def testDavidDomainAcceptsJPG(self):
        self.newSession().mailFrom('holiday-snaps@example.com')\
                         .rcptTo('victim@dnorth.net').data(self.messageWithAttachment('test.jpg'))

    def testDavidDomainAcceptsJpgZip(self):
        self.newSession().mailFrom('holiday-snaps@example.com')\
                         .rcptTo('victim@dnorth.net').data(self.messageWithAttachment('contains-pics.zip'))

    def messageWithAttachment(self, filename):
        msg = MIMEMultipart()
        msg['From'] = 'evil-spammer@example.com'
        msg['To'] = COMMASPACE.join('wherever@example.org')
        msg['Date'] = formatdate(localtime=True)
        msg['Subject'] = 'This is a subject about .exe and or .zip'

        msg.attach(MIMEText('Test message body'))

        part = MIMEBase('application', "octet-stream")
        part.set_payload( open(filename,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(filename))
        msg.attach(part)
        return msg.as_string()

The tests (both positive and negative cases) helped me to hammer out a couple of initial bugs. I really don’t know how anyone runs a live e-mail service without this sort of reassurance when tweaking the settings.

P.S. In the 48 hours since it went live, the new check has rejected over 60 messages, all of them containing a single .exe buried inside a ZIP. Many, but not all, of the messages are purporting to be from Amazon, and a surprising variety of different hosts are sending them, presumably part of a botnet of compromised machines.

Sometimes, you just don’t want to be right

It’s been a few years since I “enjoyed” writing code to mangle Microsoft Office documents, but I’ve been getting back into such things at work lately. My team and I had lots of fun yesterday tracking down the source of a bug in POI which led to Excel mangling comments when the file was saved. Frankly, I wasn’t sure to be delighted or disgusted that the “fix” was changing an ID value in the XML output. Yes, it would seem that a so-called arbitrary identifier has significance to Excel beyond cross-referencing elements in the same file, and using the same not-so-arbitrary identifier written by Excel itself dissuades it from trashing the file on save.

Call blockers

Thanks to the magic of VoIP (worth a string of blog posts in its own right), I haven’t had a real landline phone in years. But many traditionalists, notably my parents, still do. And when you’ve had the same number for 30 years, despite being registered with the TPS, you tend to get a lot of junk calls. Often, these come from abroad.

TalkTalk deserve mention for being better than BT in that they don’t have the cheek to charge for caller ID (though you do have to dig into their website to turn it on). But still, scrambling to reach a handset and see “unknown” flash up on the display so you can reject the call is tedious. And it only works for extensions which are modern enough to have a display.

All this did lead to an excellent Christmas present idea for my parents, though – devices called call blockers exist which can automate rejection/filtering of calls from unknown numbers.

My first attempt was the CPR All-in-One Call Blocker. My advice would be “don’t bother” – the unit I got was dead on arrival, and its use of non-BT sockets made it hard to daisy-chain my parents’ wired extensions off the output side of it. It’s a flimsy black box which inspires no confidence.

So I upped the ante and ordered them a TrueCall. This has proved much more like it – easy enough for my mother to install; uses standard BT sockets on both the input and output sides; Just Works. It’s blocking an average of two calls a day, and my parents are delighted with it. And, despite mixed reports on the internet, connecting the extension wiring to the output socket allowed my parents’ two wired extensions and cordless phone to all take advantage. As the icing on the cake, mum was happy to program it using the touch-tone interface rather than the website, which means that she won’t need to cough up a subscription after year 1.

It’s also worth noting that the TrueCall is a much more complete solution – rather than blocking withheld callers and a blacklist of numbers, it can be set up to reject anonymous/foreign calls, it has both white and blacklists and it can challenge callers to identify themselves – it rings the phone, plays their name, and the recipient can then decide whether to pick up or bin the call.

Update  – so I’ve now visited my parents and seen the unit for myself. Three months in, they’re absolutely delighted with it, and a peek at the logs show that it’s rejected a large number of withheld and foreign calls. It takes over answer-phone functionality, so again, a trip to TalkTalk’s website to disable their default voicemail was required.