<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Greg Hughes]]></title>
  <link href="http://ghughes.com/atom.xml" rel="self"/>
  <link href="http://ghughes.com/"/>
  <updated>2012-01-10T18:03:25+00:00</updated>
  <id>http://ghughes.com/</id>
  <author>
    <name><![CDATA[Greg Hughes]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[auth-user-pass for Synology OpenVPN]]></title>
    <link href="http://ghughes.com/blog/2011/12/05/openvpn-auth-user-pass-support-for-synology-vpn-center/"/>
    <updated>2011-12-05T18:13:00+00:00</updated>
    <id>http://ghughes.com/blog/2011/12/05/openvpn-auth-user-pass-support-for-synology-vpn-center</id>
    <content type="html"><![CDATA[<p>Since my post about <a href="http://ghughes.com/blog/2011/11/06/putting-a-synology-diskstation-to-good-use/">Putting a Synology DiskStation to Good Use</a>, a number of people have emailed me to report the following error:</p>

<blockquote><p>Mon Dec 5 18:08:48 2011 Sorry, &#8216;Auth&#8217; password cannot be read from a file</p></blockquote>

<p>Another one I&#8217;ve seen is:</p>

<blockquote><p>Failed to enable OpenVPN. Please check the configuration file</p></blockquote>

<p>These errors occur when your VPN provider requires password authentication. Some providers include the password in a file so you don&#8217;t have to type it in; others require you to type it in whenever you log on.</p>

<p>Synology compiled their build of OpenVPN with password file support disabled, as is standard for OpenVPN builds. Fortunately, there is a one-byte patch to <code>/usr/local/synovpn/sbin/openvpn</code> which reverses that: just change the byte at <code>0x21113</code> from <code>0A</code> to <code>EA</code>. This modifies the control flow within OpenVPN to permit reading from password files. (Note that this will only work on OpenVPN 2.1.4 for ARM, built by Synology on 24/08/2011, with MD5 hash <code>d6305ae735b3e49c360fc1be5eccb539</code>.)</p>

<p>I&#8217;ve prepared a pre-patched copy, which is <a href="http://dl.wifisyncapp.com/misc/ovpn-syno-patched.zip">available for download here</a>. Follow these instructions to get it working:</p>

<ol>
<li><p>(<strong>Skip this</strong> if you aren&#8217;t prompted for a username/password when you connect to your VPN provider.) Create a file named <code>pass.txt</code> in <code>/usr/syno/etc/synovpn/openvpn</code> &#8211; the first line should be your username; the second should be your password. Then add <code>auth-user-pass pass.txt</code> to <code>openvpn.conf.user</code>.</p></li>
<li><p>Replace <code>/usr/local/synovpn/sbin/openvpn</code> with the one provided above.</p></li>
<li><p>Make the replacement executable: <code>chmod +x /usr/local/synovpn/sbin/openvpn</code></p></li>
</ol>


<p>Please let me know whether this worked for you by leaving a note in the comments.</p>

<p class="important">
    Update: <a href="http://dl.wifisyncapp.com/misc/ovpn-syno-x86-patched.zip">download this instead</a> if your Synology device has an x86 CPU. You can <a href="http://forum.synology.com/wiki/index.php/What_kind_of_CPU_does_my_NAS_have">check here</a> if you&#8217;re not sure.
</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Locca Sure Touch + iPhone + Arduino]]></title>
    <link href="http://ghughes.com/blog/2011/11/27/locca-sure-touch-plus-iphone-plus-arduino/"/>
    <updated>2011-11-27T16:13:00+00:00</updated>
    <id>http://ghughes.com/blog/2011/11/27/locca-sure-touch-plus-iphone-plus-arduino</id>
    <content type="html"><![CDATA[<p><a href="http://ghughes.com/images/posts/locca/door-large.jpg"><img class="right" src="http://ghughes.com/images/posts/locca/door-small.jpg"></a></p>

<p>The front door to our house is augmented by a motorised door opener, which is controlled by a <a href="http://www.locca.co.uk/access.php">Locca Access</a> receiver. We have a bunch of remote keys that trigger the Locca receiver to open the door, but I started thinking: wouldn&#8217;t it be great to be able to trigger the door opener from an iOS or Android device?</p>

<p>Since the <em>&#8216;KeeLoq&#8217;</em> code hopping algorithm (the cornerstone of the Locca system) <a href="http://www.emsec.rub.de/media/crypto/attachments/files/2011/03/africacrypt2009_keeloq.pdf">was broken back in 2009</a>, my first thought was to reverse-engineer the remote keys and attempt to build a clone with a supplementary Wi-Fi chip. Further investigation indicated that the specialist equipment necessary to execute the required attacks against KeeLoq would be prohibitively expensive.</p>

<p>My next idea was to modify a genuine Locca remote key so it could be triggered artificially. The artificial trigger could either be mechanical, i.e. use a motor to push the button, or electronic, i.e. simulate a button push by providing power to the <a href="http://ww1.microchip.com/downloads/en/devicedoc/40138c.pdf">HCS200</a> KeeLoq encoder chip and RF transmitter. It&#8217;s  cleaner and more reliable to trigger the remote electronically, if possible.</p>

<h2>Modifying the Locca Remote Key</h2>

<p>Upon opening the casing of the remote &#8211; which is surprisingly difficult &#8211; it appears to be a simple circuit with a tiny push button situated between the power source (2x CR2032 3V batteries) and the rest of the components. When you push the button, the circuit is completed, the components are powered up, and the KeeLoq chip gets to work.</p>

<p><a href="http://ghughes.com/images/posts/locca/remote-large.jpg"><img src="http://ghughes.com/images/posts/locca/remote-small.jpg"></a></p>

<p>In theory, if we bypass the push button by completing the circuit around it, the above chain of events should occur and the door will open. I tested this theory by soldering two wires to each side of the button. As expected, the door opens when the wires are crossed. I got out my <a href="http://www.arduino.cc/en/Main/arduinoBoardUno">Arduino Uno</a> and added a transistor, thus completing the remote key circuit when the base terminal is pulled high (achieved by a <code>digitalWrite</code> on the Arduino).</p>

<p><a href="http://ghughes.com/images/posts/locca/arduino-large.jpg"><img src="http://ghughes.com/images/posts/locca/arduino-small.jpg"></a></p>

<h2>Controlling the Arduino from afar</h2>

<p>Of course, we still need a way to tell the Arduino to perform that <code>digitalWrite</code> from an iPhone. There are two viable modes of communication: Bluetooth or Wi-Fi. Bluetooth doesn&#8217;t carry many advantages, other than the fact that Bluetooth shields for Arduino boards are fairly common and well documented. However, we&#8217;d need to design a protocol and deal with the intricacies of Bluetooth on iOS &#8211; no thanks.</p>

<p>For this prototype, I decided to connect the Arduino Uno to an external server via USB, and to use serial-over-USB to signal it to trigger the remote key. The Arduino sketch looks like this:</p>

<div><script src='https://gist.github.com/1398029.js?file='></script>
<noscript><pre><code>const int basePin = 2;

void triggerRemote() {
  digitalWrite(basePin, HIGH);
  delay(2000);
  digitalWrite(basePin, LOW);
}

void setup() {
  pinMode(basePin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() &gt; 0) {
    Serial.read();
    triggerRemote();
  }
}</code></pre></noscript></div>


<p>When a byte is received via the serial line, <code>triggerRemote</code> is called, and the door should open. Clearly the iPhone can&#8217;t directly write to the serial line, so I wrote a <a href="https://github.com/ghughes/locca-arduino/tree/master/server/locca.py">small HTTP interface in Python</a> which listens on the LAN and writes a byte to <code>/dev/ttyACM0</code> (the Arduino Uno&#8217;s serial character device on Linux) when a suitable request is received. This runs on the machine that the Uno is connected to. Now any device on the LAN can now open the door with a single HTTP request.</p>

<h2>Putting it all together</h2>

<p>All that&#8217;s left to do is create a simple app to serve as a wrapper around the HTTP interface:</p>

<p><a href="http://ghughes.com/images/posts/locca/app-large.jpg"><img src="http://ghughes.com/images/posts/locca/app-small.jpg"></a></p>

<p>When you tap the yellow button, a HTTP request is dispatched in the background, and the door opener springs to life. Here it is in action:</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/00mjG_PYaAU" frameborder="0" allowfullscreen></iframe>


<h2>Downloads</h2>

<p>This is free and unencumbered software released into the public domain. Please see the <a href="http://unlicense.org/">Unlicense</a> for further details.</p>

<!-- * [Download the schematic (PDF)](#) -->


<ul>
<li><a href="https://github.com/ghughes/locca-arduino/tree/arduino/locca.pde">Download the Arduino sketch</a></li>
<li><a href="https://github.com/ghughes/locca-arduino/tree/master/server/locca.py">Download the Python server</a></li>
<li><a href="https://github.com/ghughes/locca-arduino/tree/master/iphone">Download the iPhone app</a></li>
<li><a href="https://github.com/ghughes/locca-arduino/tree/master/android">Download the Android app</a></li>
<li><a href="https://github.com/ghughes/locca-arduino">Browse the Git repository</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Varnish with Django for high performance caching]]></title>
    <link href="http://ghughes.com/blog/2011/11/11/using-varnish-with-django-for-high-performance-caching/"/>
    <updated>2011-11-11T18:20:00+00:00</updated>
    <id>http://ghughes.com/blog/2011/11/11/using-varnish-with-django-for-high-performance-caching</id>
    <content type="html"><![CDATA[<p><a href="https://www.varnish-cache.org/">Varnish</a> is an open source web cache. It sits in front of Apache (or nginx, gunicorn, etc) and caches entire pages by URL, thus vastly improving the speed of any dynamic website. Instead of repeatedly generating a page which makes many expensive SQL queries or performs some other computationally expensive task, the resulting page and its headers are cached in memory or to a file on disk. Subsequent requests for a URL are fetched directly from the cache. This provides a significant speed boost to any non-trivial <a href="http://www.djangoproject.com/">Django</a> project.</p>

<p>Of course, one can use <a href="https://docs.djangoproject.com/en/dev/topics/cache/">Django&#8217;s built-in cache framework</a> with or without Varnish. Django is great at caching parts of generated pages, but in my opinion it&#8217;s better to use a dedicated HTTP accelerator if you want to cache whole pages.</p>

<h2>Configuring Varnish for use with Django</h2>

<p>Varnish uses VCL files for configuration. These give precise control over every aspect of the request pipeline; VCL is essentially a mini language for specifying how an incoming request should be handled.</p>

<p>I use the following VCL for production Django sites, most of which is borrowed from <a href="http://bitkickers.blogspot.com/2011/09/varnish-caching-for-unauthenticated.html">Chase Seibert</a>:</p>

<div><script src='https://gist.github.com/1367443.js?file='></script>
<noscript><pre><code>sub vcl_recv {
    # unless sessionid/csrftoken is in the request, don't pass ANY cookies (referral_source, utm, etc)
    if (req.request == &quot;GET&quot; &amp;&amp; (req.url ~ &quot;^/static&quot; || (req.http.cookie !~ &quot;sessionid&quot; &amp;&amp; req.http.cookie !~ &quot;csrftoken&quot;))) {
        remove req.http.Cookie;
    }

    # normalize accept-encoding to account for different browsers
    # see: https://www.varnish-cache.org/trac/wiki/VCLExampleNormalizeAcceptEncoding
    if (req.http.Accept-Encoding) {
        if (req.http.Accept-Encoding ~ &quot;gzip&quot;) {
            set req.http.Accept-Encoding = &quot;gzip&quot;;
        } elsif (req.http.Accept-Encoding ~ &quot;deflate&quot;) {
            set req.http.Accept-Encoding = &quot;deflate&quot;;
        } else {  
            # unknown algorithm  
            remove req.http.Accept-Encoding;
        }
    }
}

sub vcl_fetch {
    # static files always cached 
    if (req.url ~ &quot;^/static&quot;) {
       unset beresp.http.set-cookie;
       return (deliver);  
    }

    # pass through for anything with a session/csrftoken set
    if (beresp.http.set-cookie ~ &quot;sessionid&quot; || beresp.http.set-cookie ~ &quot;csrftoken&quot;) {
       return (pass);
    } else {
       return (deliver);
    }
}</code></pre></noscript></div>


<p>It makes the following adjustments to Varnish&#8217;s behaviour:</p>

<ul>
<li><p><strong>All cookies except for <code>csrftoken</code> and <code>sessionid</code> are ignored.</strong> Varnish will stop serving cached pages when cookies are set; this includes cookies set by Google Analytics or other client-side JavaScript code. By ignoring these cookies, Varnish will still serve cached content to unauthenticated users. Authenticated users will never see a cached page.</p></li>
<li><p><strong><code>Accept-Encoding</code> is normalized</strong> to ensure that Varnish doesn&#8217;t cache multiple copies of the same page. Browsers tend to  differ slightly in how they specify <code>Accept-Encoding</code>, and Varnish uses it as a differentiator when calculating the hash key for a given request.</p></li>
<li><p><strong>URLs beginning with <code>/static</code> are always cached.</strong> Static content is likely to remain the same whether a user is logged in or not, so we remove cookies from these requests to ensure that they get cached.</p></li>
</ul>


<h3>Caveats</h3>

<p>Even with these adjustments in place, there are still two major caveats:</p>

<ol>
<li><p>If an object changes after being cached, there will be an unspecified delay before those changes become visible to unauthenticated users.</p></li>
<li><p>Once a user logs in or accesses a form with <a href="https://docs.djangoproject.com/en/dev/ref/contrib/csrf/">CSRF protection</a>, they will never see a cached page again unless they erase the <code>csrftoken</code> and/or <code>sessionid</code> cookies, even after logging out. Django doesn&#8217;t delete the <code>sessionid</code> cookie upon logout; instead, the session is regenerated and a new <code>sessionid</code> is set.</p></li>
</ol>


<h2>python-varnish and django-varnish</h2>

<p>To solve caveat #1, we must purge an object&#8217;s URL from the Varnish cache after it has been changed. <a href="https://github.com/justquick/django-varnish"><code>django-varnish</code></a> does just that: it monitors certain models and purges an object&#8217;s <code>get_absolute_url</code> when the object is updated. I use <a href="https://github.com/kennu/django-varnish">a fork</a> which can also purge the entire cache when certain models are updated.</p>

<p><code>django-varnish</code> depends on <a href="https://github.com/justquick/python-varnish"><code>python-varnish</code></a>, which provides a simple Python API for management of Varnish servers via their <a href="https://www.varnish-cache.org/trac/wiki/ManagementPort">management ports</a>.</p>

<h3>Installation</h3>

<p>Unfortunately the original maintainer&#8217;s code no longer works with the current version of Varnish, but alternative up-to-date forks are available. These can installed via <code>pip</code>:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>pip install -e git://github.com/kennu/python-varnish#egg=varnish
</span><span class='line'>pip install -e git://github.com/kennu/django-varnish#egg=django-varnish</span></code></pre></td></tr></table></div></figure>


<h3>Configuration</h3>

<p>Once installed, just add <code>django.contrib.humanize</code> and <code>varnishapp</code> to <code>INSTALLED_APPS</code>, add <code>(r'^admin/varnish/', include('varnishapp.urls'))</code> to your URLconf, and add some settings:</p>

<ul>
<li><p><code>VARNISH_WATCHED_MODELS</code> is a list of installed models whose <code>get_absolute_url</code>s you want to purge from the Varnish cache upon saving. Example: <code>('auth.user','profiles.profile')</code></p></li>
<li><p><code>VARNISH_GLOBAL_WATCHED_MODELS</code> is a list of installed models who will purge the entire Varnish cache upon saving.</p></li>
<li><p><code>VARNISH_MANAGEMENT_ADDRS</code> is a list of Varnish cache addresses with their management ports. Example: <code>('server1:6082','server2:6082')</code></p></li>
<li><p><code>VARNISH_SECRET</code> is the shared secret used to authenticated with the Varnish server. This can be found at <code>/etc/varnish/secret</code> on an Ubuntu/Debian installation of Varnish.</p></li>
</ul>


<p>Once you&#8217;ve set all of that up, changes to an object will result in the object&#8217;s absolute URL being purged from your Varnish cache.</p>

<h2>Delete Django session cookies upon logout</h2>

<p>Solving caveat #2 requires a behavioural change to Django: we need to delete the <code>csrftoken</code> and <code>sessionid</code> cookies after the <code>django.contrib.auth.views.logout</code> view is called. We could try to <a href="http://en.wikipedia.org/wiki/Monkey_patch">monkey patch</a> this view, or we can write a small piece of <a href="https://docs.djangoproject.com/en/dev/topics/http/middleware/">middleware</a> to do the job. Monkey patching is a terrible, terrible crime, so I went for the middleware option instead.</p>

<p>Create a file named <code>middleware.py</code> in your project&#8217;s root directory:</p>

<div><script src='https://gist.github.com/1367640.js?file='></script>
<noscript><pre><code>from django.conf import settings

&quot;&quot;&quot;Delete sessionid and csrftoken cookies on logout, for better compatibility with upstream caches.&quot;&quot;&quot;
class DeleteSessionOnLogoutMiddleware(object):
    def process_response(self, request, response):
        if getattr(request, '_delete_session', False):
            response.delete_cookie(settings.CSRF_COOKIE_NAME, domain=settings.CSRF_COOKIE_DOMAIN)
            response.delete_cookie(settings.SESSION_COOKIE_NAME, settings.SESSION_COOKIE_PATH, settings.SESSION_COOKIE_DOMAIN)
        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        try:
            view_name = '.'.join((view_func.__module__, view_func.__name__))
            # flag for deletion if this is a logout view
            request._delete_session = view_name in ('django.contrib.admin.sites.logout', 'django.contrib.auth.views.logout')
        except AttributeError:
            pass # if view_func doesn't have __module__ or __name__ attrs
</code></pre></noscript></div>


<p>Then add this new middleware to the beginning of <code>MIDDLEWARE_CLASSES</code> in your project&#8217;s settings file.</p>

<h2>Results</h2>

<p>I ran <a href="http://httpd.apache.org/docs/2.0/programs/ab.html"><code>ab</code></a> against the homepage of a project I&#8217;ve been working on recently, testing against both Varnish and Apache. At the time of testing, each direct request for the page resulted in a total of 50 database queries. I tested from the machine where the site is hosted.</p>

<p>I used the following arguments: <code>-n 1000 -c 50 -k</code>. This instructs it to perform 1000 requests with a concurrency level of 50, with HTTP persistent connections enabled.</p>

<p>The results (below) highlight why it&#8217;s absolutely necessary to employ a proper caching strategy for your production Django deployments. Whether you use Varnish, or another HTTP accelerator, or even Django&#8217;s built-in whole page cache, the implications are clear: if you allow users to hit Apache directly on every page load, your site won&#8217;t stay online for long.</p>

<table class="figure">
    <tr>
        <td></td>
        <th>requests/sec</th>
        <th>50% served within</th>
        <th>95% served within</th>
    </tr>
    <tr>
        <th>Apache 2.2.21</th>
        <td>4.10</td>
        <td>2441ms</td>
        <td>3096ms</td>
    </tr>
    <tr>
        <th>Varnish 3.0.2</th>
        <td>20204.88</td>
        <td>1ms</td>
        <td>5ms</td>
    </tr>
</table>


<p>(<strong>Update:</strong> It was suggested within the comments that I run <code>ab</code> with the <code>-k</code> argument to enable HTTP persistent connections, so I repeated the test and amended the results above.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Putting a Synology DiskStation to good use]]></title>
    <link href="http://ghughes.com/blog/2011/11/06/putting-a-synology-diskstation-to-good-use/"/>
    <updated>2011-11-06T11:03:00+00:00</updated>
    <id>http://ghughes.com/blog/2011/11/06/putting-a-synology-diskstation-to-good-use</id>
    <content type="html"><![CDATA[<p>I recently purchased the <a href="http://www.amazon.co.uk/gp/product/B0047CNXJ2/ref=as_li_tf_tl?ie=UTF8&amp;amp;tag=ghughes-21&amp;amp;linkCode=as2&amp;amp;camp=1634&amp;amp;creative=6738&amp;amp;creativeASIN=B0047CNXJ2">Synology DiskStation DS211j</a>. It&#8217;s quite a steal: for £150, you get an awesome NAS device (bring your own HDD) with an ungodly number of extra features that you wouldn&#8217;t find in any other consumer NAS. The web interface is also very well designed, built using <a href="http://www.sencha.com/products/extjs/">Ext JS 3</a> - a refreshing departure from the typically archaic web interfaces found on consumer network hardware.</p>

<p>One of its most useful features is the so-called <a href="http://www.synology.com/us/products/features/downloadstation2.php">Download Station</a>. This allows you to upload torrents, NZBs and HTTP links to the NAS and it does the rest; downloads are completed automatically in the background. It is lacking in a few areas, however, and is superseded by dedicated software such as <a href="http://www.transmissionbt.com/">Transmission</a> and <a href="http://sabnzbd.org/">SABnzbd</a>. The good news is that both of these applications (and many others) can also be installed onto any compatible Synology NAS via &#8216;Synology package files&#8217; (SPKs).</p>

<h2>Zebulon&#8217;s SPK Repository</h2>

<p>Zebulon maintains an <a href="http://synopkg.superzebulon.org/spkrepo/packages">SPK repository</a> with a selection of third-party applications; one just needs to add that repository to the Package Center to start installing applications from it.</p>

<p><img src="http://ghughes.com/images/posts/synology/package-center-add-repo.png"></p>

<p>After logging in to DSM, open up the Package Center application and click <em>Settings</em>. Then select <em>Package Sources</em> and click <em>Add</em>. Enter the following details:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Name: Zebulon's SPK Repository
</span><span class='line'>Location: http://synopkg.superzebulon.org/spkrepo/packages</span></code></pre></td></tr></table></div></figure>


<p>Once you&#8217;ve added the repository, select the <em>Other Sources</em> tab in Package Center. You&#8217;ll now see a list of the application packages maintained by Zebulon. From here, installing Transmission or SABnzbd is simply a matter of clicking <em>Install</em>. Once an application is installed, visit the <em>Installed</em> tab to activate it.</p>

<p><strong>A word of warning:</strong> it&#8217;s important that you create a new, separate shared folder for each application to store its downloaded content. Otherwise, you&#8217;ll run into permission errors.</p>

<p>So now life is good: your Synology NAS can perform download tasks all by itself. But what if you wanted to connect through an encrypted VPN service for additional privacy? Or perhaps you&#8217;re forced to because your ISP throttles BitTorrent and Usenet traffic. Fortunately, there is a solution.</p>

<h2>Installing the OpenVPN client</h2>

<p>Under the <em>Available</em> tab in Package Center, there is a list of official Synology packages. One of these is <em>VPN Server</em>, which is described as offering &#8216;an easy VPN solution that turns your DiskStation into a VPN server&#8217;. With a bit of configuration tweaking, however, it&#8217;s possible to turn this into a VPN <em>client</em> instead. Install the package, but don&#8217;t activate it yet.</p>

<p>Your VPN provider should have provided sets of OpenVPN config files. If you use Viscosity on a Mac, these can be found in <code>~/Library/Application Support/Viscosity/OpenVPN</code>. You&#8217;ll need two <code>.crt</code> files and a <code>.key</code> file, plus the <code>.conf</code> configuration file. <a href="http://forum.synology.com/wiki/index.php/How_to_setup_an_sftp-server">SFTP into the DiskStation</a> and drop these files into <code>/usr/syno/etc/synovpn/openvpn</code>, renaming the <code>.conf</code> file to <code>openvpn.conf.user</code>.</p>

<p>Now activate <em>VPN Server</em> in Package Center. These configuration changes effectively transform the VPN &#8216;server&#8217; into a client; now, while this package is active, an OpenVPN daemon will be kept alive in the background and all outgoing connections from the NAS will be routed through the VPN. Now, any Transmission and SABnzbd traffic coming from your NAS is SSL encrypted and protected against traffic shaping.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hotpatching the PlayStation 3's hypervisor and kernel]]></title>
    <link href="http://ghughes.com/blog/2011/01/16/hotpatching-the-playstation-3s-hypervisor-and-kernel/"/>
    <updated>2011-01-16T00:00:00+00:00</updated>
    <id>http://ghughes.com/blog/2011/01/16/hotpatching-the-playstation-3s-hypervisor-and-kernel</id>
    <content type="html"><![CDATA[<p>Recently, I took a short break from <em>Wi-Fi Sync</em> to jump into the PS3 hacking scene. It&#8217;s currently at a point where you can install userland packages, such as FTPDs and SNES emulators, but you can&#8217;t manipulate the hypervisor or GameOS kernel. It’s still very much a closed system.</p>

<p>As an iPhone developer with an app on <a href="http://cydia.saurik.com/">Cydia</a>, I can see great potential within the PS3. It’s crying out for a decent package manager, but you need OS-level access to do that effectively. Unlocking the PS3 in this way has other benefits too; the system can be modified in any way you wish. The gates are effectively thrown open.</p>

<p>So today I’m releasing three tools which open the PS3’s hypervisor (lv1) and GameOS kernel (lv2) to full read/write access from packaged userland applications. These tools can be used to create and test kernel patches in RAM, which negates the risk of bricking your PS3 by flashing it with an incorrectly patched binary. You can also use the tools to create a patched lv1 or lv2 binary, if you wish, although I suggest thoroughly testing your patches in RAM first.</p>

<h2>Disclaimer</h2>

<p>I don&#8217;t condone piracy and these tools <strong>do not</strong> enable copied games to run on the PS3. To rephrase: these tools will not allow backup managers to suddenly start working. The tools are packaged in source code form and do not include any Sony code or other Sony assets such as encryption keys. If you’re not a developer, these tools will be useless to you, so please do not try to use them.</p>

<h2>Tools I&#8217;m releasing today</h2>

<ul>
<li><p><code>resign_self.py</code>. This allows you to automatically replace any segment within a self and re-sign the self so the signature and hashes are all valid again. Similar to <code>makeself</code>, but it is more suited towards patching lv1 and lv2 (and has already been used for this purpose).</p></li>
<li><p><code>insert_lv1_lv2.py</code>. This is just a convenience script I made to take a modified, re-signed <code>lv1.self</code> and <code>lv2_kernel.self</code>, and automatically create a PUP which is identical to an original PUP except for those two files.</p></li>
<li><p><code>lv1dumper</code>. This is an application which runs on the PS3 that you can compile and package using <a href="http://psl1ght.com/">PSL1GHT</a> and geohot’s tools. After running it, lv1 will be mapped at <code>0x8000000014000000</code> with read/write access, and you will be able to poke lv2 without the system shutting down to protect itself. It disables the new lv2 memory hashing feature Sony added to 3.55 (probably to stop future USB jailbreaks). It can also be used to dump lv1.</p></li>
</ul>


<p><code>lv1dumper</code> requires that some patches to lv1 and lv2 are already in place. I’ll now describe how to add these patches. They have been tested but I cannot guarantee that they won’t brick your console.</p>

<h2>Adding necessary patches for lv1dumper</h2>

<p>You need to extract and decrypt code segments from <code>lv1.self</code> and <code>lv2_kernel.self</code> (just use <code>unself</code> and copy them directly out of the ELF), and make the following changes to to them, assuming you’re using 3.55:</p>

<p>(<strong>Update:</strong> the code segment is not the entire ELF file, it’s inside the ELF file. Use <code>readelf</code> to find out where it is. You need to copy it out of the ELF into a separate file.)</p>

<ul>
<li><p><code>lv1_undocumented_function_114</code> in lv1 must be patched so that it can be used to map any area of real memory. graf_chokolo found this trick months ago, but it still applies here. Patch the byte at <code>D5A47</code> from <code>00</code> to <code>01</code> (it&#8217;s at <code>2D5A47</code> in IDA) in segment 1.</p></li>
<li><p>You then need to add peek and poke to lv2. Patch <code>1933C</code> to <code>E8 63 00 00 60 00 00 00</code> and <code>19348</code> to <code>F8 83 00 00 60 00 00 00</code> in segment 0.</p></li>
</ul>


<p>You can then use <code>resign_self.py</code> to re-insert your patched code segment back into the self. You’ll firstly need to change a few bytes in some useless strings because of the way zlib deflate works; the script will tell you what to do. I found that changing strings was the easiest way to do this, it just takes a bit of trial and error.</p>

<p>Finally, use <code>insert_lv1_lv2.py</code> to create your modified PUP. You’ll need to update to the PUP, then install geohot’s jailbreak PUP over the top of it. If you’ve done everything right, <code>lv1dumper</code> should just exit after you run it and you’ll have r/w access to lv1 and lv2 (peek and poke). The <code>lv1_peek</code>, <code>lv1_poke</code>, <code>lv2_peek</code> and <code>lv2_poke</code> functions in <code>lv1dumper</code> should illustrate how that access can be used.</p>

<p>I’m hoping that some interesting and innovative stuff can come out of this; perhaps we can start to see unofficial apps enjoying the same success on the PS3 that they do on the iPhone.</p>

<p><a href="https://github.com/ghughes/ps3tools">Download from Github</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Wi-Fi Sync: Milestone]]></title>
    <link href="http://ghughes.com/blog/2010/09/05/wi-fi-sync-a-milestone/"/>
    <updated>2010-09-05T00:00:00+01:00</updated>
    <id>http://ghughes.com/blog/2010/09/05/wi-fi-sync-a-milestone</id>
    <content type="html"><![CDATA[<p><a href="http://ghughes.com/wifi-sync/">Wi-Fi Sync</a> recently reached the 20,000 sales milestone; huge thanks to everyone who has purchased the app. This is a fantastic achievement for the iPhone jailbreak scene.</p>

<p>Work on <a href="http://ghughes.com/wifi-sync/beta/">Wi-Fi Sync 2.0</a> is progressing well. The new release will fix the outstanding issues reported by a small number of users, in addition to some new features such as sync-over-3G support. You’ll also be able to disable automatic backups for wirelessly connected devices only, rather than disabling backups for all devices (even those connected via USB) as with the current version. 2.0 will also be far friendlier to those who like to manage their own startup items; you’ll be able to start and exit Wi-Fi Sync whenever you like, and you can choose whether to run it at startup. I don’t even plan to ship an installer - instead you’ll be able to copy the app into Applications, like many other Mac apps. It will require iTunes 10. I’ll have more news shortly.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Wi-Fi Sync]]></title>
    <link href="http://ghughes.com/blog/2010/05/17/wi-fi-sync/"/>
    <updated>2010-05-17T00:00:00+01:00</updated>
    <id>http://ghughes.com/blog/2010/05/17/wi-fi-sync</id>
    <content type="html"><![CDATA[<p>When I started work on what would eventually become <a href="http://ghughes.com/wifi-sync/">Wi-Fi Sync</a>, I couldn’t have predicted the fantastic success that it’s enjoyed over the last week. The app has already sold 3,000 copies, and articles have appeared on <a href="http://www.engadget.com/tag/Greg+Hughes/">Engadget</a>, <a href="http://techcrunch.com/2010/05/14/hands-on-with-the-wifisync-app/">TechCrunch</a>, <a href="http://www.bbc.co.uk/blogs/thereporters/rorycellanjones/2010/05/still_here_the_teenage_app_tyc.html">BBC News</a>, <a href="http://www.bbc.co.uk/programmes/p008lqww">BBC Radio</a>, <a href="http://gizmodo.com/5538689/now-available-a-10-app-whichll-sync-your-jailbroken-iphone-to-itunes-over-wi+fi">Gizmodo</a>, <a href="http://www.wired.com/gadgetlab/2010/05/apple-rejects-wi-fi-sync-app-for-iphone/">Wired</a> and many foreign language blogs. Thanks to everyone who has sent suggestions, comments and feedback.</p>

<p>I’ve had a lot of questions about iPad and Windows support. I think I’ve had a breakthrough with the iPad (largely thanks to <a href="https://github.com/comex">comex</a>, author of the <a href="https://github.com/comex/spirit">Spirit</a> jailbreak), so expect more news on that very soon.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Virtual PC images for IE6 and IE7 compatibility testing]]></title>
    <link href="http://ghughes.com/blog/2009/10/25/virtual-pc-images-for-ie6-and-ie7-compatibility-testing/"/>
    <updated>2009-10-25T11:07:00+00:00</updated>
    <id>http://ghughes.com/blog/2009/10/25/virtual-pc-images-for-ie6-and-ie7-compatibility-testing</id>
    <content type="html"><![CDATA[<p>I’ve just come across <a href="http://web.archive.org/web/20091123223305/http://www.microsoft.com/Downloads/details.aspx?FamilyID=21eabb90-958f-4b64-b5f1-73d0a413c8ef&amp;displaylang=en">these Microsoft-provided Virtual PC hard disk images</a> for testing sites in legacy versions of IE. If you’ve ever suffered the hell of trying to install and maintain different versions of IE using registry hacks or 3rd party solutions, you’ll be relieved to hear there’s now a better (and free) option.</p>

<p>Images of XP SP3 and Vista are available. They’re currently set to expire on 01/01/2010.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PHP 5.2.6 zip extension for MAMP]]></title>
    <link href="http://ghughes.com/blog/2009/10/20/php-5-dot-2-6-zip-extension-for-mamp/"/>
    <updated>2009-10-20T20:04:00+01:00</updated>
    <id>http://ghughes.com/blog/2009/10/20/php-5-dot-2-6-zip-extension-for-mamp</id>
    <content type="html"><![CDATA[<p>If you use MAMP for local PHP development and try to access the <code>ZipArchive</code> class, you might find yourself on the receiving end of an error message similar to this one:</p>

<blockquote><p>Class &#8216;ZipArchive&#8217; not found in /home/&#8230;</p></blockquote>

<p>MAMP doesn’t come with PHP’s zip extension, so you either have to compile it yourself or drop a precompiled copy into your extensions directory. Compiling is a pain and precompiled extensions are hard to come by, so to save time, download it <del>here</del> and copy to <code>/Applications/MAMP/bin/php5/lib/php/extensions/no-debug-non-zts-20050922</code>. (<strong>Update:</strong> Link no longer available.)</p>

<p>Don’t forget to enable it within <code>php.ini</code>. You&#8217;ll also need to make the downloaded file executable: <code>chmod +x zip.so</code></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Silverlight 3.0 on OSx86]]></title>
    <link href="http://ghughes.com/blog/2009/10/19/silverlight-3-dot-0-on-hackintosh/"/>
    <updated>2009-10-19T10:22:00+01:00</updated>
    <id>http://ghughes.com/blog/2009/10/19/silverlight-3-dot-0-on-hackintosh</id>
    <content type="html"><![CDATA[<p>Upon attempting to install Silverlight 3.0 on my &#8216;hackintoshed&#8217; Dell Mini 10v, I found that it wouldn’t play ball due to an incompatibility with PowerPC (despite the fact that the machine uses an Intel processor).</p>

<p>I’ve modified the installer so it skips the CPU check, and will thus install on PPC-based Macs and OSx86 machines. You can download it here: <del>Silverlight.3.0.pkg</del>. (<strong>Update:</strong> Link no longer available.)</p>
]]></content>
  </entry>
  
</feed>

