PogoPlug as a Siri Proxy

UPDATE 2012-02-03: I realized I forgot about installing the certificate on the non-4S device. Fixed!

UPDATE 2012-02-04: amanpatel pointed out on the ArchLinuxArm forums that you need to make sure base-devel is installed. I’ve updated the prerequisites section to include this.

My wife got an iPhone 4S recently, which of course features Siri, the virtual assistant. I didn’t think I needed a 4S, but I was pretty jealous of Siri. Unfortunately, I don’t qualify for a discounted upgrade since I got my iPhone4 less than a year ago.

Enter Spire by @chpwn. Spire lets you install Siri on a jailbroken iPhone, but it requires the use of a proxy that lets non-4S devices pretend to be a 4S. I found lots of instructions for getting a proxy up and running as a virtual machine, but I don’t like leaving full computers running all the time. I decided to figure out what would be required to make it work with what we had: a PogoPlug server.

Back in December I picked up a PogoPlug on sale for $20 shipped from J&R Music/Computer World. $20 for a plug computer that can run a real version of Linux is an awesome deal (I’m excited about the Raspberry Pi, but that isn’t available yet). After trying out the installed version of Linux, I decided to put ArchLinuxArm on it for some more flexibility. It turns out this device is perfectly suited to act as a SiriProxy server!

Necessary Items:

  1. Device running ArchLinux (I used a PogoPlug B01 model for this, but I think any other ArchLinux machine will probably work as well)
  2. USB hard disk or flash drive for keeping system files (there isn’t enough space on the internal flash memory for the entire system)
  3. Router set to redirect traffic on ports 53 and 443 to your PogoPlug if your PogoPlug does not have an external IP address.
  4. iPhone 4S (doesn’t need to be jailbroken)
  5. iPhone 4 (jailbroken)
Acknowledgements: https://gist.github.com/1552448

Okay, now for the work.

Prerequisites

  1. Make sure you’ve got your ArchLinux system up and running. I won’t go into that here – follow the guide on the ArchLinuxArm site if you’ve got the same PogoPlug model as me.
  2. We’ve got to install a few packages (explanations for some of them are below). Luckily, pacman can handle these. Login to your box as root and run:
    pacman -Sy dnsmasq git ruby zlib ruby-ncurses ruby-pkgconfig make base-devel

    Note that we will not be using rvm, as many other tutorials for this recommend. rvm is meant to simplify switching between various versions of ruby, but since we have limited resources on our PogoPlug, we’ll just be making sure that we’re running the correct version of Ruby system-wide.

  3. We’ve also got to set up a few Ruby gems. These are pretty automated, but they took a while to complete on my pogoplug:
    gem install rake bundler
  4. Make note of your external IP address. If your IP is not static, you’ll need to make sure you have some sort of dynamic DNS service in place so you can access your pogoplug from outside of your home network.

dnsmasq

dnsmasq is a simple DNS forwarder/rewriter. We will use this to spoof the iPhone 4S into talking to our SiriProxy instead of the real Siri servers.

  1. Edit /etc/dnsmasq.conf and create an entry to redirect guzzoni.apple.com to our server (replace XX.XX.XX.XXwith your IP address), like so:
    # Add domains which you want to force to an IP address here.
    # The example below send any host in double-click.net to a local
    # web-server.
    #address=/double-click.net/127.0.0.1
    address=/guzzoni.apple.com/XX.XX.XX.XX
  2. Test your configuration by running:
    rc.d checkconfig dnsmasq

    You should receive the following message indicating it works:

    dnsmasq: syntax check OK.
  3. Start dnsmasq by running:
    rc.d start dnsmasq
  4. You can test that dnsmasq is properly rewriting requests to guzzoni.apple.com by running the following in a Terminal app:
    host guzzoni.apple.com XX.XX.XX.XX

    You should receive a response like the following:

    Using domain server:
    Name: XX.XX.XX.XX
    Address: XX.XX.XX.XX#53
    Aliases:
    
    guzzoni.apple.com has address XX.XX.XX.XX

    Your pogoplug’s IP address should be showing up in all three places.

Certificates

SiriProxy uses certificates as part of spoofing the real Siri servers. This can cause some complications if you want to be able to use SiriProxy on your local LAN as well as on the Internet. The solution is to generate a dual certificate.

  1. Edit /etc/openssl.cnf. Look for:
    commonName = Common Name (eg, YOUR name)
    commonName_max = 64

    and replace it with:

    0.commonName = Common Name (eg, YOUR name)
    0.commonName_default = your.dynamic.hostname.com
    0.commonName_max = 64
    1.commonName = Common Name (eg, YOUR name)
    1.commonName_default = guzzoni.apple.com
    1.commonName_max = 64

    Change your.dynamic.hostname.com to whatever dynamic hostname you are using (http://freedns.afraid.org/ works really well for me).

  2. Generate the certificates. You will be prompted to enter some things with the lines below – you should be able to leave most of them set to their default values just by hitting the enter key. The main exception is that you will need to type in passphrases during the generation process – just pick them when it asks you to come up with one, and re-enter it at the later phases that require it.
    mkdir -p /root/.siriproxy
    cd /root/.siriproxy
    
    openssl genrsa -des3 -out ca.key 4096
    openssl req -new -x509 -days 365 -key ca.key -out ca.crt
    
    openssl genrsa -des3 -out server.key 4096
    
    openssl req -new -key server.key -out server.csr
    
    openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.passless.crt
    
    openssl rsa -in server.key -out server.key.insecure
    
    mv server.key server.key.secure
    mv server.key.insecure server.passless.key
  3. Copy the ca.crt file to your desktop. I have an SMB server set up on my pogoplug that makes this very simple.

SiriProxy

There are several forks of SiriProxy. I found the master branch in plamoni’s githubto work fine for our set up (just two people sharing a single key).

  1. Clone the SiriProxy code into /root/SiriProxy using git. (Note: because SiriProxy needs to listen on port 443, it needs to be run as root)
    cd /root
    git clone git://github.com/westbaer/SiriProxy.git
  2. Use rake to install siriproxy to /usr/lib for system-wide use:
    rake install
  3. Bundle siriproxy (I guess this installs any plugins you’ve set up and updates the certificates. You should run this any time you generate new certificates or change the configuration, I think):
    siriproxy bundle
  4. Start the siriproxy server:
    siriproxy server

iPhone 4S

Remember, you don’t need to jailbreak the iPhone 4S for this to work!

Install Certificate

  1. E-mail the ca.crt file from above to an e-mail account on your iPhone 4S.
  2. Open up the e-mail on your 4S device, then open the certificate by tapping it.
  3. Install the certificate by tapping the Install button, then tap Done.

Change DNS

  1. Open up the Settings app, and go into Wifi settings.
  2. Tap on the blue arrow to the right of your wifi network’s name to get detailed settings.
  3. In the DNS field, put the IP address of your pogoplug at the very beginning of the line.

Test SiriProxy

  1. Open up Siri on your 4S device by holding down the Home button, and say “Test Siri Proxy.” Siri should respond with, “Siri Proxy is up and running!” You should also see a bunch of lines scroll by on the siriproxy server window.
  2. If you don’t get anything, then double-check that you have completed everything above. You need your 4S device to have connected to the proxy in order for the rest of these steps to work.

iPhone 4 (not 4S)

INSTALL CERTIFICATE

UPDATE 2012-02-03: I had originally forgotten about this section.

  1. E-mail the ca.crt file from above to an e-mail account on your iPhone 4S.
  2. Open up the e-mail on your 4S device, then open the certificate by tapping it.
  3. Install the certificate by tapping the Install button, then tap Done.

Install Siri

Make sure your jailbroken phone (the one that doesn’t yet have Siri) is connected to Wifi. Spire will require ~100 MB of data to be downloaded, so this could take a while.

  1. Open up Cydia, and install the packages OpenSSH, Erica Utilities, and Spire. If you haven’t set up OpenSSH before and/or you haven’t set your passwords, you definitely want to do that. Refer to the Cydia guide for more information on OpenSSH.
  2. Go into the Settings app, and choose Spire. Enter https://your.dynamic.hostname.com as your proxy host, using the dynamic hostname you are using.
  3. Go back to the main Settings, tap on General, then Siri, and turn Siri on.
  4. Attempt to use Siri by holding down the Home button (the proximity sensor won’t work with non-4S devices).
  5. After it fails, ssh into your non-4S device (default username: root, default password: alpine). You can get the IP address by looking at your Wifi settings details. Run the following command:
    plutil -show /User/Library/Preferences/com.apple.assistant.plist

    You should get output that looks something like this:

    {
        Accounts =     {
            "12345678-90AB-CDEF-01234-567890ABCDEF" =         {
                "Ace Host" = "665414ff-75ab-42b2-9473-5aa74fb11533";
                "Assistant Identifier" = "";
                Hostname = "https://your.dynamic.hostname.com";
                "Last Assistant Data Anchor" = "";
                "Last Sync Dates" =             {
                    "com.apple.alarm.label" = 2012-01-29 21:33:50 +0000;
                    "com.apple.contact.people" = 2012-01-29 21:33:48 +0000;
                    "com.apple.media.entities" = 2012-01-29 21:33:52 +0000;
                    "com.apple.reminder.list.name" = 2012-01-29 21:33:50 +0000;
                };
                "Speech Identifier" = "";
                "Validation Expiration" = 2012-01-30 22:01:50 +0000;
            };
        };
        "Session Language" = "en-US";
    }

    If you’re missing some of the above fields, don’t worry – we’re going to fix that. Pay careful attention to the first string of numbers and letters after the word “Accounts” (12345678-90AB-CDEF-01234-567890ABCDEF in the example above). This is your unique hex key.

  6. Run the following commands to update your Siri plist file, replacing 12345678-90AB-CDEF-01234-567890ABCDEF with your unique hex key from above (copy and paste!):
    plutil -key "Accounts" -key "784ECD19-25FD-46E3-A28A-92DFD892255F" -key "Ace Host" -value "" /User/Library/Preferences/com.apple.assistant.plist
    
    plutil -key "Accounts" -key "784ECD19-25FD-46E3-A28A-92DFD892255F" -key "Assistant Identifier" -value "" /User/Library/Preferences/com.apple.assistant.plist
    
    plutil -key "Accounts" -key "784ECD19-25FD-46E3-A28A-92DFD892255F" -key "Speech Identifier" -value "" /User/Library/Preferences/com.apple.assistant.plist
  7. Open up Siri on your non-4S device by holding down the Home button, and say “Test Siri Proxy” just like you did before with the 4S device. Siri should respond with, “Siri Proxy is up and running!” If you made it this far, congratulations! Siri is working on your non-4S device!

Automating Services on the PogoPlug

Okay, so we’ve got it up and running, but if we lose power everything crashes. It would be nice if we could ensure it was automatically started every time our PogoPlug rebooted. To do this, we need to add a daemon script for siriproxy and tell our pogoplug to automatically start dnsmasq and siriproxy.

First, let’s create an rc.d script for sirirproxy. This is based on the ArchLinux sample rc.d script for crond. Edit /etc/rc.d/siriproxy to look like the following:

#!/bin/bash

. /etc/rc.conf
. /etc/rc.d/functions

DAEMON=siriproxy
ARGS=server

export HOME=/root
PID=`pidof -o %PPID /usr/bin/ruby /usr/bin/$DAEMON`

[ -r /etc/conf.d/$DAEMON ] && . /etc/conf.d/$DAEMON

case "$1" in
  start)
    stat_busy "Starting $DAEMON"
    if [ -z "$PID" ] ; then
      $DAEMON $ARGS 1>/dev/null 2>/dev/null &
      add_daemon $DAEMON
      stat_done
    else
      stat_fail
      exit 1
    fi
    ;;
  stop)
    stat_busy "Stopping $DAEMON"
    [ -n "$PID" ] && kill $PID &> /dev/null
    if [ $? = 0 ]; then
      rm_daemon $DAEMON
      stat_done
    else
      stat_fail
      exit 1
    fi
    ;;
  restart)
    $0 stop
    sleep 1
    $0 start
    ;;
  *)
    echo "usage: $0 {start|stop|restart}"
esac

You will also need to make this file executable:

chmod a+x /etc/rc.d/siriproxy

Now that we’ve got an rc.d script set up, let’s test it out.

rc.d restart siriproxy

Stopping siriproxy may fail, if it wasn’t already running. Starting siriproxy should print DONE.

Now we just need to make dnsmasq and siriproxy start automatically on boot. Edit /etc/rc.conf, and go down to the end where the start-up daemons are listed. Add dnsmasq and siriproxy inside these parentheses, like so:

DAEMONS=(set-oxnas-mac !hwclock syslog-ng network netfs crond sshd openntpd samba dnsmasq siriproxy)

(You may have other things listed differently – just make sure dnsmasq and siriproxy are in here).

Lastly, reboot your pogoplug by running the following:

reboot

Give it a minute or two to start up, then try out Siri on both your 4S device and your non-4S device by saying “Test Siri Proxy.” Make sure to pause a little bit between them – Apple has been known to ban Siri if it’s used too much.

One final note: it’s important that the 4S device connects to the proxy at least once a day. This is because it gets new keys from Apple every now and then, which it needs to share with the proxy server in order for the non-4S device to be able to use them.

I hope this helps someone!

2 responses

  1. Hello,
    I am having trouble following your instructions, I am stuck at:
    [root@alarm ~]# rc.d checkconfig dnsmasq
    -bash: rc.d: command not found
    This is my second try, yesterday, I Googled to get past this and other failing steps, but could not get Siri to work.
    I am trying again hoping for help..

    Thanks

  2. Unfortunately, at this point ArchLinuxArm has become significantly different, and I don’t think the instructions as I posted them will work any more. Since I now have a phone that has Siri built in, I’m no longer interested in keeping these instructions up to date. Good luck, though!

Leave a Reply