New uses for old Dash buttons

I recently acquired a few Amazon Dash buttons and wondered if they might be repurposed to serve some useful purpose, other than ordering groceries.

I found this article by Ted Benson in which he describes how Dash buttons send an ARP probe after joining the WiFi network. By listening for these ARP probes (and their unique MAC addresses) you can trigger IFTTT Webhooks workflows, which turns the humble Amazon ordering tool into a customisable IoT button.

Bob Steinbeiser replied to Ted’s post with a clever Python script which sniffs ARP packets using a raw socket. Having played with Bob’s script I set about trying to make a few improvements. I’m a novice when it comes to Python though, so forgive my amateur code.

import socket
import struct
import binascii
import urllib2
import time

# Based on an original script by Bob Steinbeiser (https://medium.com/@xtalker)
# Adapted to ignore duplicate presses and added support for multiple IFTTT triggers

# Use your own IFTTT Webhooks key here - see https://ifttt.com/maker_webhooks
ifttt_key = 'abc123'

# MAC addresses and their corresponding IFTTT Webhooks triggers
things = {
    'aabbccddeeff' : ['lights_off', 'sockets_off'],
    'a0b1c2d3e4f5' : ['test_1', 'test_2', 'test_3']
}

last_success={}

for macaddr in things:
    last_success[macaddr] = 0

rawSocket = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003))

while True:
    packet = rawSocket.recvfrom(2048)

    ethernet_header = packet[0][0:14]
    ethernet_detailed = struct.unpack('!6s6s2s', ethernet_header)

    arp_header = packet[0][14:42]
    arp_detailed = struct.unpack('2s2s1s1s2s6s4s6s4s', arp_header)

    # Skip non-ARP packets
    ethertype = ethernet_detailed[2]
    if ethertype != '\x08\x06':
        continue

    source_mac = binascii.hexlify(arp_detailed[5])

    time_now = int(time.time())

    # Is this a known 'thing' ?
    if source_mac in things:

        trigger_list = things[source_mac]

        # Prevent duplicate presses from being actioned (within 10 secs)
        if time_now > last_success[source_mac] + 10:
 
            # Supports multiple IFTTT Webhook triggers
            for trigger in trigger_list:

                print "Device " + source_mac + " has triggered " + trigger
                last_success[source_mac] = int(time.time())
                data = '{ "value1" : "' + source_mac + '", "value2" : "' + trigger + '" }'
                req = urllib2.Request('https://maker.ifttt.com/trigger/' + trigger + '/with/key/' + ifttt_key, data, {'Content-Type': 'application/json'})
                f = urllib2.urlopen(req)
                response = f.read()
                f.close()
                print response

         else:
             print "Ignoring repeated event for " + source_mac

    else:
        print "Ignoring unknown device " + source_mac

Note that this Python script doesn’t work on Mac OS, due to the lack of support for AF_PACKET sockets.

Advertisements

Sky Hub syslogging to Mac OS

The standard issue Sky Broadband SR102 ADSL router includes the capability to send syslog messages to a remote host.

Unfortunately the plucky little SR102 doesn’t send syslog messages in entirely the right format (checked using ‘syslog -F raw’):

[ASLMessageID 303320877] [Time 1463491448] [TimeNanoSec 0] [Level 2]
 [PID 4294967295] [UID 4294967294] [GID 4294967294] [ReadGID 80] [Host
 1] [Sender 2016-05-17T14] [Facility daemon] [Message 24:08.000Z
 skyhub.ihr syslog - - [skySDID@32666 mac="7C4CA5D9E148"
 sn="A502141D002081"]  Administrator login successful from IP:
 192.168.0.100 .]

You can however still use Mac OS’s syslog daemon to receive these messages, but first you’ll need to enable the socket listener:

cd /System/Library/LaunchDaemons
sudo /usr/libexec/PlistBuddy -c "add :Sockets:NetworkListener dict" com.apple.syslogd.plist
sudo /usr/libexec/PlistBuddy -c "add :Sockets:NetworkListener:SockServiceName string syslog" com.apple.syslogd.plist
sudo /usr/libexec/PlistBuddy -c "add :Sockets:NetworkListener:SockType string dgram" com.apple.syslogd.plist

To restart the syslog daemon:

sudo launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist
sudo launchctl load /System/Library/LaunchDaemons/com.apple.syslogd.plist

Next go into the Sky Hub web interface, click on the Security tab (default admin credentials are admin / sky), select Logs and then enter the IP address of your Mac in the Syslog server address.

You can check for Sky Hub syslog entries in /var/log/system.log

To filter out the Sky Hub messages into a separate log file, add these two lines to /etc/asl.conf and then restart the syslog daemon again:

# Sky SR102 broadband router saved to skyhub.log
? [S= Message skyhub.ihr ] file skyhub.log mode=0640 format=bsd rotate=seq compress all_max=50M

The query-action rule tells syslogd to match on the “skyhub.ihr” substring in the Message key and then save those entries to /var/log/skyhub.log. The options are for log file rotation, retaining up to 50MB of files.

Typical Sky Hub log entries will include connection retraining, web interface logins and NTP synchronisations.

Re-signing iOS apps

I am occasionally presented with a packaged iOS .ipa archive by a third-party developer, which is intended for in-house distribution (using an Apple Developer Enterprise certificate), or for App Store distribution using a different developer account.

Re-signing is a quick and simple way of delivering an app when a developer won’t provide you with their Xcode project source from which to spin your own build.

I previously used the iReSign utility to accomplish this, but found that this wouldn’t work in all cases, in particular when the app includes linked frameworks or libraries (which results in errors such as “DYLD, Library not loaded“).

To solve this I wrote the shell script below. It takes an existing .ipa archive, embeds your own developer provisioning profile, replaces any existing code signatures and packages it again for distribution.

Please use with my compliments and leave a comment if this helps you out.

(Note: This script has a dependency on command line tools such as PlistBuddy and codesign, so you will likely need to install Apple’s Xcode developer tools)

Replace DEVCERT with the Common Name of your own Apple developer certificate.

#!/bin/bash
# Re-sign an IPA with specified developer certificate (present in keychain)

DEVCERT="iPhone Distribution: Your Developer Cert Name"
TMPDIR="tmpwork"
SOURCEIPA="$1"
MOBILEPROV="$2"
BUNDLEID="$3"

if [ $# -eq 0 ]

then
  echo "Usage: $0 [app.ipa] [provprofile] [bundleid]"
else
  if [ ! -e "$SOURCEIPA" ]
  then
    echo "Error: $SOURCEIPA not found"
    exit
  fi

  if [ ! -e "$MOBILEPROV" ]
  then
    echo "Error: $MOBILEPROV not found"
    exit
  fi

  SIGNEDAPP=`echo $SOURCEIPA | awk -F".ipa" '{ printf ("%s-signed.ipa", $1) }'`
  unzip -qo "$SOURCEIPA" -d $TMPDIR
  APP=$(ls ${TMPDIR}/Payload/)

  if [ ! -z "$BUNDLEID" ]
  then
     echo "Changing Bundle ID to ${BUNDLEID}";
     /usr/libexec/PlistBuddy -c "Set:CFBundleIdentifier $BUNDLEID" "${TMPDIR}/Payload/${APP}/Info.plist"
  fi

  cp "$MOBILEPROV" "${TMPDIR}/Payload/${APP}/embedded.mobileprovision"
  security cms -D -i "${TMPDIR}/Payload/${APP}/embedded.mobileprovision" > Entitlements_full.plist
  /usr/libexec/PlistBuddy -x -c 'Print:Entitlements' Entitlements_full.plist > Entitlements.plist
  echo "Re-signing with certificate: $DEVCERT"

  for folder in `find -d ${TMPDIR} \( -name "*.app" -or -name "*.appex" -or -name "*.framework" -or -name "*.dylib" \)`; do
    /usr/bin/codesign --continue -f -s "$DEVCERT" --entitlements "Entitlements.plist" "$folder"
  done

  echo "Package the signed IPA"
  cd $TMPDIR
  zip -qry ../${SIGNEDAPP} *
  cd ..
  rm -rf $TMPDIR
  rm Entitlements_full.plist

fi

EncFS for OS X Yosemite

securecloud It’s about time I updated my instructions for installing and running an EncFS filesystem on Mac OS X, synchronised to Dropbox. Use a combination of FUSE for OS X, EncFS, Dropbox and DropSec to create and maintain a super-secure filesystem which syncs with the cloud, while maintaining

  1. Download and install FUSE for OS X (the MacFUSE compatibility layer is not required)
  2. If you don’t have it already, install the Homebrew package manager
  3. Download and install EncFS (v1.7.5_1 at time of writing) and any dependencies, it’s as easy as ‘brew install homebrew/fuse/encfs
  4. Download DropSec, extract DropSec.app from the archive and copy it to your Applications folder

To create a new encrypted volume (stored locally at first to prevent your EncFS key from being synchronised with Dropbox):

encfs ~/Desktop/_Encrypted ~/Documents/_DropSec

Answer ‘yes’ when prompted to create the new folders and choose ‘p’ for pre-configured paranoia mode (256-bit AES encryption). Enter a secure EncFS password when prompted and you’re done. Now the filesystem has been created we can deal with securing the key.

umount ~/Documents/_DropSec
mkdir ~/.keys
mv ~/Desktop/_Encrypted/.encfs6.xml ~/.keys/dropsec.xml

The commands above move your key from the EncFS filesystem into a hidden folder in your (local) home directory Now move the entire ~/Desktop/_Encrypted folder (minus your key) into your Dropbox:

mv ~/Desktop/_Encrypted ~/Dropbox/

To mount the secure filesystem run the DropSec app from your Application folder. The first time you run DropSec it will prompt you for your EncFS password which it stores in your local login keychain. The password must match the secure password you set earlier.

When the secure volume is mounted a DropSec folder with a padlock icon will appear on your desktop. If it doesn’t, check that you have ‘Show Connected servers’ checked in Finder preferences.

To mount or unmount the encrypted volume simply run the DropSec app. For convenience copy it to your Mac OS dock for quick access.

WhatsApp Web is keeping my Mac awake

The new WhatsApp Web client is a welcome companion to the hugely popular WhatsApp Messenger cross-platform mobile application. It allows users to link their browser to their WhatsApp account and interact with chat sessions just like you do in the mobile app.

So far so good, but I have encountered one significant drawback. If you run the web client in a Google Chrome session on Mac OS X then a kernel assertion is established which prevents the system from sleeping, regardless of energy saver system preferences.

With the WhatsApp Web client running:

$ /usr/bin/pmset -g assertions
2015-01-29 17:47:11 +0000 
Assertion status system-wide:
 BackgroundTask 0
 ApplePushServiceTask 0
 UserIsActive 0
 PreventUserIdleDisplaySleep 0
 PreventSystemSleep 0
 ExternalMedia 0
 PreventUserIdleSystemSleep 1
 NetworkClientActive 0
Listed by owning process:
 pid 346(coreaudiod): [0x0006336d00011046] 00:00:50 PreventUserIdleSystemSleep named: "com.apple.audio.context532.preventuseridlesleep" 
 Created for PID: 12006.

With the WhatsApp Web session closed:

$ /usr/bin/pmset -g assertions
2015-01-29 17:47:23 +0000 
Assertion status system-wide:
 BackgroundTask 0
 ApplePushServiceTask 0
 UserIsActive 0
 PreventUserIdleDisplaySleep 0
 PreventSystemSleep 0
 ExternalMedia 0
 PreventUserIdleSystemSleep 0
 NetworkClientActive 0

I assume that this sleep issue is related to the notification feature of WhatsApp Web, since the assertion references Mac OS X’s coreaudiod process. Turning off desktop alerts and sounds in the client settings does not fix it however, so for the moment it doesn’t seem possible to prevent this system insomnia from occurring.

I shall contact WhatsApp product support and see what they can do.

Software bloat is not an Apple invention

Smartphone

The New York Times reporter Catherine Rampell has caused a stir with her article ‘Cracking the Apple Trap‘, in which she insinuates that Apple are employing planned obsolescence to slow down older devices and force customers into buying new products.

It’s certainly a common complaint in the IT industry, one most often directed at Microsoft and it’s Windows operating system. Search for ‘software bloat‘ and you’ll see what mean:

Software bloat is a process whereby successive versions of a computer program become perceptibly slower, use more memory or processing power, or have higher hardware requirements than the previous version whilst making only dubious user-perceptible improvements.

But it’s not as sinister as is being made out. Operating systems evolve over time resulting in improvements, usually fancy new user interfaces, graphics or features. These require extra computing ‘power’, be it a faster processor or more memory to work effectively.

What we often see is slick new software trying to run on older hardware. While it might still function, there are signs that it struggles and this is where you experience freezing, sluggishness or reduced battery life due to the processor having to work harder.

From Apple’s perspective, they’re damned if they do and damned if they don’t. Which would attract more criticism, not supporting iOS 7 on iPhone 4 at all, or stretching legacy devices to their limits in order to deliver the same customer experience to as many customers as possible?

The iPhone 4 was released in June 2010, so three years of supported operating system updates could hardly be considered “planned obsolescence”. Let’s not forget that not so long ago it was nearly impossible to update the software on your mobile phone. Apple were pioneers in using software update technology. It’s not unusual now to have consumer mobile contracts lasting 18 or 24 months, this is testimony to the longevity of smartphones.

If anything Apple is guilty of doing too much to appease their loyal customers. Deliberate software bloat is just as likely to drive customers away from Apple’s products as it would force them into begrudgingly buying new hardware. What we’re talking about is technological progress and the need to lead through innovation.

The iPhone 4 was a hugely successful product globally and Apple risked alienating many millions of customers by not by including them in the much heralded iOS 7 update. Having as large a base of customers all at the same software level also helps keep Apple’s application ecosystem vibrant. Developers are keen to exploit the latest features and customers are hungry for the next killer app. By reducing software fragmentation Apple aims to keep all elements of the ecosystem happy – and maintain a healthy revenue stream as a result.

As a lapsed Apple fanboi I have no vested interest in defending Apple. I converted to Android mainly due to price and flexibility, and the realisation that I mainly use Google services. I do still have an appreciation for Apple’s products however and I understand their motivations. Apple’s business model is not about box shifting, it’s about being at the centre of the digital home through a range of connected products all offering the best possible customer experience.

At a more practical level, if you’re content running iOS 6 on your iPhone 4 then my advice is to stick with what you have. If you are tempted by iOS 7 then just be aware of the consequences of running bleeding edge software on three year old hardware.

What Innovation?

Apple reinvents the phone

I was having a discussion with an old friend who declared that there has been no innovation in mobile devices for years now. I immediately took exception to this claim and set my mind to disproving his assertion.

There is no disputing that Apple “reinvented the phone” in 2007 when they launched the original iPhone to an expectant world. I’ll never forget the looks of joy and amazement when I first demonstrated the iPhone’s touch screen interface and clever pinch and zoom gestures.

Let’s not forget how tired and utilitarian other ‘smart’ phones of the time were!

2007 Smartphones

Apple’s early dominance in the smartphone market has been successfully challenged by Google’s Android operating system and the countless slab clones churned out by Far Eastern manufacturers, but do any of them truly innovate?

What have we seen in mobile phone design in the last six years which could be considered innovative? We’ve had different form factors, sizes, colours and storage capacities, but the fundamental iPhone design concept has hardly changed.

Certainly display technology has improved, with more vibrant colours and pixel densities higher than the human eye can distinguish, but that’s evolution not innovation.

Processor power has increased, the latest smartphones boasting quad-core CPUs with dazzling performance, but this is standard Moore’s Law territory.

Camera technology has gradually improved, with manufacturers attempting to out-gun each other in the megapixel arms race. Fundamentally though it’s still a digital camera on a phone.

Mobile apps are the emperor’s new clothes, but this is just a trendy new name for what we used to call ‘computer programs’ or software.

A few new features have appeared like voice recognition, Near Field Communication (NFC) and wireless inductive charging, but these technologies have been around for years and are just being retro-fitted to mobile devices.

The sad truth though is that there hasn’t been any innovation since the original iPhone. Yes there have been gimmicks and incremental improvements, but the iPhone’s simple touch screen design and user interface has remained largely unchanged and unbettered.

Unless Apple regains the ability to surprise and delight with the unveiling of their 7th generation iPhone later on today, I’ll have to concede that my friend is right.

Please don’t leave us in 2007.

Macworld 2007 Teaser