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

  <title><![CDATA[Lyte's Blog]]></title>
  <link href="http://blog.lyte.id.au//atom.xml" rel="self"/>
  <link href="http://blog.lyte.id.au//"/>
  <updated>2017-03-14T21:54:21+11:00</updated>
  <id>http://blog.lyte.id.au//</id>
  <author>
    <name><![CDATA[Lyte]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[git perms]]></title>
    <link href="http://blog.lyte.id.au//2017/03/14/git-perms/"/>
    <updated>2017-03-14T21:30:00+11:00</updated>
    <id>http://blog.lyte.id.au//2017/03/14/git-perms</id>
    <content type="html"><![CDATA[<p>Have you ever noticed that when git mentions a file it often shows an octal permission mode that doesn&rsquo;t match with the permission on the file?</p>

<p>No? Try this, from an empty directory:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># Set umask to 0002 (i.e don&#39;t mask out user/group bits)</span>
</span><span class='line'><span class="nv">$ </span><span class="nb">umask </span>0002
</span><span class='line'><span class="c"># create a new git repo in the current dir</span>
</span><span class='line'><span class="nv">$ </span>git init .
</span><span class='line'><span class="c"># create a new file</span>
</span><span class='line'><span class="nv">$ </span>touch foo
</span><span class='line'><span class="c"># get the octal perms on it</span>
</span><span class='line'><span class="nv">$ </span>stat -c <span class="s2">&quot;0%a %n&quot;</span> foo
</span><span class='line'>0664 foo
</span><span class='line'><span class="c"># add and commit</span>
</span><span class='line'><span class="nv">$ </span>git add foo
</span><span class='line'><span class="nv">$ </span>git commit -m <span class="s2">&quot;bar&quot;</span>
</span><span class='line'><span class="o">[</span>master <span class="o">(</span>root-commit<span class="o">)</span> 51dc083<span class="o">]</span> bar
</span><span class='line'> 1 file changed, 0 insertions<span class="o">(</span>+<span class="o">)</span>, 0 deletions<span class="o">(</span>-<span class="o">)</span>
</span><span class='line'> create mode 100644 foo
</span></code></pre></td></tr></table></div></figure>


<p>So I just added a file to git that has octal perms of <code>0664</code> but git reported <code>100644</code> &ndash; it&rsquo;s safe to ignore the prefix, but why has the second last digit changed?</p>

<p>Here&rsquo;s something else to try:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># Create a file with every (practical) octal mode</span>
</span><span class='line'><span class="nv">$ </span><span class="k">for </span>file in 0<span class="o">{</span>4..7<span class="o">}{</span>0..7<span class="o">}{</span>0..7<span class="o">}</span>; <span class="k">do </span>touch <span class="nv">$file</span>; chmod <span class="nv">$file</span> <span class="nv">$file</span>; <span class="k">done</span>
</span><span class='line'><span class="c"># Stage those files</span>
</span><span class='line'><span class="nv">$ </span>git add 0???
</span><span class='line'><span class="c"># Look at what perms git has staged:</span>
</span><span class='line'><span class="nv">$ </span>git diff --staged | grep <span class="s1">&#39;^new file mode &#39;</span> | sort | uniq -c
</span><span class='line'>    128 new file mode 100644
</span><span class='line'>    128 new file mode 100755
</span></code></pre></td></tr></table></div></figure>


<p>So git took all 256 different combinations of modes we gave it and stored <code>100644</code> half the time and <code>100755</code> the other half.</p>

<p>This is because git is really only looking at the <code>u+x</code> (user execute aka <code>&amp; 0100</code>) bit &ndash; it doesn&rsquo;t care about the rest of the perms.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[X-Cache and X-Cache-Lookup Headers]]></title>
    <link href="http://blog.lyte.id.au//2014/08/28/x-cache-and-x-cache-lookupheaders/"/>
    <updated>2014-08-28T21:43:00+10:00</updated>
    <id>http://blog.lyte.id.au//2014/08/28/x-cache-and-x-cache-lookupheaders</id>
    <content type="html"><![CDATA[<p>I watched a discussion about <code>X-Cache</code> and <code>X-Cache-Lookup</code> headers unfold recently and it turns out a lot of people who I would have thought knew what these headers were indicating were a little muddled up. Further more, it turned out if you go looking for a good explanation, everyone seems to just link <a href="http://anothersysadmin.wordpress.com/2008/04/22/x-cache-and-x-cache-lookup-headers-explained/">to this rather old blog post</a> &ndash; despite being well meaning, it&rsquo;s unfortunately slightly confused too.</p>

<p>So maybe I can give a better explanation.</p>

<p>First question &ndash; where is the spec for <code>X-Cache</code>? Well, there isn&rsquo;t one &ndash; that little <code>X-</code> prefix indicates the header is not part of the spec, so its meaning <em>may</em> vary between proxy implementations (in fact with <a href="https://www.varnish-cache.org/trac/wiki/VCLExampleHitMissHeader">Varnish it&rsquo;s common to add it yourself in the config file</a>, so it could mean anything at all).</p>

<h2>Why am I seeing these headers?</h2>

<p>So with that out of the way I&rsquo;ll focus on where I think you&rsquo;re most likely to see them, <a href="http://www.squid-cache.org/">Squid</a>. Squid is a fairly common caching proxy, both as a forward (outbound) caching proxy and as a reverse (inbound/application accelerator/aggregating) proxy. <a href="https://www.google.com/search?q=site:wiki.squid-cache.org+%22x-cache%22">Squid&rsquo;s doco also fails to clearly define what the headers do</a>, so if you&rsquo;ve got here because you&rsquo;re trying to figure out what they mean, there&rsquo;s a good chance you&rsquo;ve got a Squid proxy in the mix (even if you didn&rsquo;t realise it).</p>

<h2>What they mean</h2>

<p>So, <em>with Squid</em> what these headers mean is:</p>

<ul>
<li><code>X-Cache</code>: Did this proxy serve the result from cache (HIT for yes, MISS for no).</li>
<li><code>X-Cache-Lookup</code>: Did the proxy have a cacheable response to the request (HIT for yes, MISS for no).</li>
</ul>


<p>This means if:</p>

<ul>
<li>both are HITs, you made a cacheable request and the proxy had a cacheable response that matched and it handed it back to you.</li>
<li><code>X-Cache</code> is a MISS and <code>X-Cache-Lookup</code> is a HIT, you made a request that had a cacheable response but you&rsquo;ve forced a cache bypass &ndash; usually achieved by a hard refresh, commonly activated with Ctrl+F5 or by sending the headers <code>Pragma: no-cache</code> (HTTP/1.0) or <code>Cache-Control: no-cache</code> (HTTP/1.1).</li>
<li>both are MISSes, you made a request (it doesn&rsquo;t matter if it was cacheable) and there was no corresponding response object in the proxy cache.</li>
</ul>


<p>This is completely irrelevant to browser cache &ndash; if you&rsquo;re viewing browser cache and inspecting the headers in Chrome or Firebug then you&rsquo;ll see what the status of the proxy was at the time the proxy returned it to your browser. Sorry if this is obvious, but a surprising number of people seemed to think that the browser cares and bothers to modify these headers, it doesn&rsquo;t. Really, it doesn&rsquo;t. I promise.</p>

<h2>How you can test this for yourself</h2>

<p>First, if you&rsquo;re trying to use a browser to inspect headers, understand what it&rsquo;s really saying, e.g in Google Chrome, look for the <code>(from cache)</code> next to the <code>Status Code:</code> section in the headers:</p>

<p><img src="http://blog.lyte.id.au//images/2014-08-28/chrome_from_cache.png" title="Screen shot of Chrome Inspector with Network tab open and 'Status Code: 200 OK (from cache) displayed" alt="" /></p>

<p>This means nothing has gone over the network and it brought the object out of browser cache.</p>

<p>All other browsers are left as an exercise for the reader as frankly it&rsquo;s not the right tool for the job (I just figured I had to cover one, as <em>everyone</em> seems to do it this way anyway).</p>

<p>Fire up a bash terminal and get used to curl.</p>

<p>This is what I usually run:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl -sv http://example.com/ 2&gt;&amp;1 &gt; /dev/null | egrep <span class="s1">&#39;&lt; (X-Cache|Age)&#39;</span>
</span><span class='line'>&lt; Age: 1
</span><span class='line'>&lt; X-Cache: HIT from example.com
</span><span class='line'>&lt; X-Cache-Lookup: HIT from example.com:80
</span></code></pre></td></tr></table></div></figure>


<p>There&rsquo;s a lot going on here, so lets break it down:</p>

<ul>
<li><code>curl</code>: this is the main thing we&rsquo;re running,</li>
<li><code>-sv</code>: this enables both <code>--silent</code> and <code>--verbose</code>, which (counterintuitive I know) is the simplest way to get curl in to a mode where it dumps both the body and headers out in a useful format (yes I know you can use <code>--head</code>, but that changes the request format and invalidates enough testing to make it useless).</li>
<li><code>http://example.com/</code>: our URL of choice.</li>
<li><code>2&gt;&amp;1</code>: Take STDERR (headers) and redirect it to STDOUT (so we can pipe it to <code>egrep</code>).</li>
<li><code>&gt; /dev/null</code>: Ignore the original STDOUT (body).</li>
<li><code>| egrep</code>: pipe the headers through <code>egrep</code>.</li>
<li><code>'&lt; (X-Cache|Age)</code>: grab just headers starting with <code>X-Cache</code> or <code>Age</code>.</li>
</ul>


<p>You may note I snuck that <code>Age</code> header you&rsquo;ve been ignoring in there, you can thank me later.</p>

<p>So in this first example we&rsquo;ve made a cacheable request (absent of <code>Pragma: no-cache</code> or similar headers) and the proxy has had a response from its upstream 1 second ago (<code>Age: 1</code>) that was cacheable.</p>

<p>Now that we have a basic command, lets fiddle with it to see what happens.</p>

<p>If we request the same thing, we should see the <code>Age</code> header count up by roughly the number of seconds since the start of either request:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl -sv http://example.com/ 2&gt;&amp;1 &gt; /dev/null | egrep <span class="s1">&#39;&lt; (X-Cache|Age)&#39;</span>
</span><span class='line'>&lt; Age: 5
</span><span class='line'>&lt; X-Cache: HIT from example.com
</span><span class='line'>&lt; X-Cache-Lookup: HIT from example.com:80
</span></code></pre></td></tr></table></div></figure>


<p>If we request the same thing but with a hard refresh header (note: Squid and probably every other caching proxy ever can be configured to ignore these headers on the request side, so if you get different results here, 9 times out of 10 that&rsquo;s why), we can see that the proxy had the object in cache, but didn&rsquo;t use it:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl -sv --header <span class="s2">&quot;Pragma: no-cache&quot;</span> http://example.com/ 2&gt;&amp;1 &gt; /dev/null | egrep <span class="s1">&#39;&lt; (X-Cache|Age)&#39;</span>
</span><span class='line'>&lt; X-Cache: MISS from example.com
</span><span class='line'>&lt; X-Cache-Lookup: HIT from example.com:80
</span></code></pre></td></tr></table></div></figure>


<p>If we request something we don&rsquo;t expect the proxy to have seen before, the proxy neither has it in cache or serves it from cache:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>curl -sv http://example.com/?<span class="s2">&quot;$(date -Ins)&quot;</span> 2&gt;&amp;1 &gt; /dev/null | egrep <span class="s1">&#39;&lt; (X-Cache|Age)&#39;</span>
</span><span class='line'>&lt; X-Cache: MISS from example.com
</span><span class='line'>&lt; X-Cache-Lookup: MISS from example.com:80
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[What the hell PHP?]]></title>
    <link href="http://blog.lyte.id.au//2014/05/01/what-the-hell-php/"/>
    <updated>2014-05-01T21:54:00+10:00</updated>
    <id>http://blog.lyte.id.au//2014/05/01/what-the-hell-php</id>
    <content type="html"><![CDATA[<p>Sometimes I feel like I should have an entire section on my blog dedicated solely to PHP&rsquo;s maniacle insanity just so I&rsquo;d have a place to record whatever crazy new thing I learn about PHP on any day I work with it. <strong><em>Any</em></strong> day I work with it. Ever.</p>

<p>That said, this one particulary annoyed me.</p>

<p>PHP caches stat information. Why? I dunno really, VFS caches stat information too, you&rsquo;d think it&rsquo;d do a better job being that people other than PHP core developers designed it (so maybe some of them weren&rsquo;t drunk at the time), plus it&rsquo;s actually the right layer, it can see not only file system modifications made by the PHP you&rsquo;re currently writing, but also all that other PHP you&rsquo;ve written and the stuff Mr Jones wrote, also that strange bit of code that&rsquo;s not PHP. So it would actually be able to cache the right things at VFS, instead PHP core devs actually thought it made sense to cache it in a PHP process, but what the hell lets leave OS problems to application developers and just move on.</p>

<p>So back on topic, PHP caches stat information or to put it another way, PHP has a stat cache (do you see what I did there?). Stat information are all those boring statistics you get about files when you write <code>stat &lt;file&gt;</code>, but really it&rsquo;s so much more. It&rsquo;s most of the data about a file that isn&rsquo;t actually the file itself.</p>

<p>Great, so PHP caches stat information. That must make things faster or something? Possibly, but it also just makes it a massive hot squishy steaming pile of lies. Because any interaction with a file&rsquo;s stat info is cached, if a file is modified in some way outside of PHP that you care about you now have to constantly call <code>clearstatcache()</code> so that when you check anything about the file you can be confident that PHP isn&rsquo;t lying to you.</p>

<p>Did I mention PHP has a stat cache? A-packed-full-of-lies-but-at-least-it&rsquo;s-faster-than-telling-you-the-truth-except-now-you-have-to-slow-things-down-by-constantly-clearing-it-stat-cache.</p>

<p>Somewhere about here you learn to deal with it, you think to yourself &ldquo;it&rsquo;s ok, I&rsquo;ll just call <code>clearstatcache()</code> everywhere, it&rsquo;s fine, it&rsquo;s just a stupid cache that I can&rsquo;t turn off, so I may as well deal with it, maybe I&rsquo;ll write a Vim macro to insert <code>clearstatcache()</code> calls in front of any file system operations, that&rsquo;ll fix it, it&rsquo;ll be almost like PHP is a real language&rdquo;.</p>

<p>Then, because you haven&rsquo;t written that Vim macro (it&rsquo;s a stupid idea any way) and you haven&rsquo;t managed to turn off the broken stat cache (<a href="https://bugs.php.net/bug.php?id=28790">because you can&rsquo;t</a>) you run in to what must surely be a bug &ndash; even PHP core devs couldn&rsquo;t consider this a feature, surely? You change ownership of a file using the built in <code>chown()</code> function, it&rsquo;s a glorious thing, at first it&rsquo;s owned by one user, then it&rsquo;s owned by another user, cheers go up, standing ovations, it&rsquo;s possible something built in to PHP actually works as designed. Cool. You go to check this using a PHP function (because like all PHP devs you totally do TDD and as such need to check such things) and because you updated the ownership information using a PHP function obviously the cache that PHP manages should be marked dirty and you&rsquo;ll get back an accurate result right?</p>

<p>No.</p>

<p>What?</p>

<p>No, you don&rsquo;t.</p>

<p>I&rsquo;m going to say it again&hellip; What?</p>

<p>Ok it must be a bug.</p>

<p>Oh, no, you see, actually, it&rsquo;s the <a href="http://www.php.net/manual/en/function.clearstatcache.php">first fscking example on the manual page</a>.</p>

<p>Hmmmm&hellip;.</p>

<p>Did I mention, PHP has a stat cache?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Spying with PHPUnit]]></title>
    <link href="http://blog.lyte.id.au//2014/03/01/spying-with-phpunit/"/>
    <updated>2014-03-01T12:02:00+11:00</updated>
    <id>http://blog.lyte.id.au//2014/03/01/spying-with-phpunit</id>
    <content type="html"><![CDATA[<p>Trying to spy on invocations with PHPUnit seems to normally involve either writing your own spy class:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">class IAmASpy {</span>
</span><span class='line'><span class="x">  public $invocations = array();</span>
</span><span class='line'><span class="x">  public function foo() {</span>
</span><span class='line'><span class="x">      $this-&gt;invocations []= &#39;foo&#39;;</span>
</span><span class='line'><span class="x">  }</span>
</span><span class='line'><span class="x">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>or trying to use execution checks on mock objects to determine that things were called with the right arguments:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">$mock = $this-&gt;GetMock(&#39;Foo&#39;);</span>
</span><span class='line'><span class="x">$mock-&gt;expects($this-&gt;once())</span>
</span><span class='line'><span class="x">    -&gt;method(&#39;bar&#39;)</span>
</span><span class='line'><span class="x">    -&gt;with($this-&gt;identicalTo(&#39;baz&#39;));</span>
</span></code></pre></td></tr></table></div></figure>


<h2>What A Pain!</h2>

<p>What if you want to check the arguments going in to the last call? Well you can use <code>at()</code>:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">$mock-&gt;expects($this-&gt;at(7)) // ...</span>
</span></code></pre></td></tr></table></div></figure>


<p>&hellip; better hope we never add any other calls!</p>

<p>What if we don&rsquo;t know the exact parameter that it&rsquo;s being called with and want to check it with something more complex? Well if you <a href="http://phpunit.de/manual/3.7/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.assertions.assertThat.tables.constraints">dig really hard in the manual</a> you&rsquo;ll find there&rsquo;s a whole bunch of assertions that let you feed in crazier stuff like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">// ...</span>
</span><span class='line'><span class="x">-&gt;with($this-&gt;matchesRegularExpression(</span>
</span><span class='line'><span class="x">    &#39;/Oh how I love (regex|Regular Expressions)/&#39;</span>
</span><span class='line'><span class="x">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>So that&rsquo;s pretty cool, if you happen to like really obscure features that are impossible to remember.</p>

<h2>Surely there&rsquo;s a better way? Think of the children!</h2>

<p>What if you could just ask for all the invocations and test that they were right in that language you&rsquo;re already using for all your production logic? Wouldn&rsquo;t that be just dandy!</p>

<p>Turns out you can, but it&rsquo;s hiding &ndash; and I don&rsquo;t mean it&rsquo;s hiding in a &ldquo;you will find this if you read the manual&rdquo; kind of way, I mean it&rsquo;s hiding in the source code, where everyone totally looks first for easy examples right?</p>

<p>All you have to do is store the result of <code>$this-&gt;any()</code> and you can use it as a spy:</p>

<figure class='code'><figcaption><span></span></figcaption><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='php'><span class='line'><span class="x">$exec-&gt;expects($spy = $this-&gt;any())</span>
</span><span class='line'><span class="x">    -&gt;method(&#39;foo&#39;);</span>
</span></code></pre></td></tr></table></div></figure>


<p>(I&rsquo;ve got to wonder if documenting those extra 7 characters might be the colloquial straw that breaks the PHPUnit manual&rsquo;s back.)</p>

<p>Now that you have a spy, you can just do normal stuff that calls it, then use normal PHP logic (I had to laugh when I wrote &ldquo;normal PHP logic&rdquo;) to confirm it&rsquo;s right:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">// get the last invocation</span>
</span><span class='line'><span class="x">$invocation = end($spy-&gt;getInvocations());</span>
</span><span class='line'><span class="x">$this-&gt;assertEquals(&#39;foo&#39;, $invocation-&gt;arguments[0]);</span>
</span></code></pre></td></tr></table></div></figure>


<h2>An Example You Say?</h2>

<p>As a concrete example, lets ensure the NSA is spying on its citizens just the right amount.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="cp">&lt;?php</span>
</span><span class='line'><span class="c1">// What we&#39;re testing today</span>
</span><span class='line'><span class="k">class</span> <span class="nc">AverageCitizen</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">spyOn</span><span class="p">()</span> <span class="p">{}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Our tests (yes, normally these would be in some other file)</span>
</span><span class='line'><span class="k">class</span> <span class="nc">TestAverageCitizens</span> <span class="k">extends</span> <span class="nx">PHPUnit_Framework_TestCase</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">testSpyingLikeTheNSAShould</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$citizen</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getMock</span><span class="p">(</span><span class="s1">&#39;AverageCitizen&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$citizen</span><span class="o">-&gt;</span><span class="na">expects</span><span class="p">(</span><span class="nv">$spy</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">any</span><span class="p">())</span>
</span><span class='line'>            <span class="o">-&gt;</span><span class="na">method</span><span class="p">(</span><span class="s1">&#39;spyOn&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$citizen</span><span class="o">-&gt;</span><span class="na">spyOn</span><span class="p">(</span><span class="s2">&quot;foo&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$invocations</span> <span class="o">=</span> <span class="nv">$spy</span><span class="o">-&gt;</span><span class="na">getInvocations</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">assertEquals</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$invocations</span><span class="p">));</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// we can easily check specific arguments too</span>
</span><span class='line'>        <span class="nv">$last</span> <span class="o">=</span> <span class="nb">end</span><span class="p">(</span><span class="nv">$invocations</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">assertEquals</span><span class="p">(</span><span class="s2">&quot;foo&quot;</span><span class="p">,</span> <span class="nv">$last</span><span class="o">-&gt;</span><span class="na">parameters</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">public</span> <span class="k">function</span> <span class="nf">testSpyingLikeTheNSADoes</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$citizen</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getMock</span><span class="p">(</span><span class="s1">&#39;AverageCitizen&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$citizen</span><span class="o">-&gt;</span><span class="na">expects</span><span class="p">(</span><span class="nv">$spy</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">any</span><span class="p">())</span>
</span><span class='line'>            <span class="o">-&gt;</span><span class="na">method</span><span class="p">(</span><span class="s1">&#39;spyOn&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$citizen</span><span class="o">-&gt;</span><span class="na">spyOn</span><span class="p">(</span><span class="s2">&quot;foo&quot;</span><span class="p">);</span>
</span><span class='line'>        <span class="nv">$citizen</span><span class="o">-&gt;</span><span class="na">spyOn</span><span class="p">(</span><span class="s2">&quot;bar&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$invocations</span> <span class="o">=</span> <span class="nv">$spy</span><span class="o">-&gt;</span><span class="na">getInvocations</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>        <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">assertEquals</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">count</span><span class="p">(</span><span class="nv">$invocations</span><span class="p">));</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="cp">?&gt;</span><span class="x"></span>
</span></code></pre></td></tr></table></div></figure>


<p>and when we run the tests we can see that even PHPUnit knows the NSA has crossed the line:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='php'><span class='line'><span class="x">$ phpunit --debug test.php </span>
</span><span class='line'><span class="x">PHPUnit 3.6.10 by Sebastian Bergmann.</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'><span class="x">Starting test &#39;TestAverageCitizens::testSpyingLikeTheNSAShould&#39;.</span>
</span><span class='line'><span class="x">.</span>
</span><span class='line'><span class="x">Starting test &#39;TestAverageCitizens::testSpyingLikeTheNSADoes&#39;.</span>
</span><span class='line'><span class="x">F</span>
</span><span class='line'>
</span><span class='line'><span class="x">Time: 0 seconds, Memory: 3.25Mb</span>
</span><span class='line'>
</span><span class='line'><span class="x">There was 1 failure:</span>
</span><span class='line'>
</span><span class='line'><span class="x">1) TestAverageCitizens::testSpyingLikeTheNSADoes</span>
</span><span class='line'><span class="x">Failed asserting that 2 matches expected 1.</span>
</span><span class='line'>
</span><span class='line'><span class="x">/i/be/a/coder/test.php:35</span>
</span><span class='line'>
</span><span class='line'><span class="x">FAILURES!</span>
</span><span class='line'><span class="x">Tests: 2, Assertions: 4, Failures: 1</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Keep Cron Simple Stupid]]></title>
    <link href="http://blog.lyte.id.au//2013/11/08/keep-cron-simple-stupid/"/>
    <updated>2013-11-08T08:54:00+11:00</updated>
    <id>http://blog.lyte.id.au//2013/11/08/keep-cron-simple-stupid</id>
    <content type="html"><![CDATA[<p>Someone brought up from our Sys Admin chat at work yesterday that <a href="http://www.hcidata.info/crontab.htm">crontab and % are insane</a>, the summary was:</p>

<blockquote><p>If you want the % character in a command, as part of a cronjob:<br/>
1. You escape the %, so it becomes \%<br/>
2. echo and pipe the command you want to run (with the escaped %) into sed<br/>
3. Have sed unescape the %<br/>
4. Pipe it into the original program</p></blockquote>

<p>Which I responded to with roughly &ldquo;if you want a &lsquo;%&rsquo; in your cron line you actually want a shell script instead&rdquo;&hellip; this turns out to be a great <del>argument</del>debate as a lot of very good Sys Admins (who were online at the time) completely disagreed with me until I&rsquo;d spelled out my argument in more detail.</p>

<h2>Problems with cron</h2>

<ul>
<li>The syntax can be quite insane if you&rsquo;re expecting it to behave like shell (hint: <code>cron != shell</code>)</li>
<li>There&rsquo;s no widely used crontab linter (I was going to leave it at &ldquo;there&rsquo;s no crontab linter&rdquo;, but found <a href="https://github.com/lyda/chkcrontab#crontab-linter">chkcrontab</a> while writing this, which looks like a good start but isn&rsquo;t packaged for any distro I&rsquo;ve checked yet)</li>
<li>Badly breaking syntax in a crontab file will cause all jobs in that file to stop running (usually with no error recorded anywhere)</li>
<li>Unless you&rsquo;re double entering your scheduling information you&rsquo;re not going to be able to pick up the absense of the job in your monitoring solution when it fails to run</li>
<li>I&rsquo;m stupid (yes this is a problem with cron)</li>
</ul>


<p>All of these have led me to break cron lots of times and even more times I&rsquo;ve had to try to figure out why a scheduled job isn&rsquo;t running after someone else has broken it for me. Happy days.</p>

<h2>KISS</h2>

<p>Whenever I&rsquo;m breaking something fairly critical too often for comfort, it&rsquo;s time to <a href="http://en.wikipedia.org/wiki/KISS_principle">Keep It Simple Stupid</a> and the way I&rsquo;ve tried to do that with cron is to never ever put anything complicated on a cron line.</p>

<p>Lets take a simple example:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>* * * * * echo % some % percents % for % you %</span></code></pre></td></tr></table></div></figure>


<p>Intuitively I&rsquo;d just expect that to do what it does on the shell (echo&rsquo;s back the string, which in cron would normally make it back to someone in email form), but instead the first % will start STDIN for the command, the remaining %s will get changed to new lines and you&rsquo;ll end up with an echo statement that just echo&rsquo;s a single new line out to cron as it&rsquo;s not interested in the STDIN fed to it.</p>

<p>This creates a testing problem because now to test the behaviour of the cron line I need to wait for cron to run the cron line (there&rsquo;s no way to immediately confirm the validity of the line).</p>

<p>If we instead place the behaviour we want in a script:</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'>#!/bin/bash -e
</span><span class='line'>echo % some % percents % for % you %</span></code></pre></td></tr></table></div></figure>


<p>and call that from cron:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>* * * * * /path/to/script</span></code></pre></td></tr></table></div></figure>


<p>You can be reasonably confident that it&rsquo;ll do exactly the same thing when cron runs it as when you test it on the terminal.</p>

<h2>But % is ok when it&rsquo;s simple</h2>

<p>Some people tried to make the argument that a % is really ok when it&rsquo;s actually really simple, e.g.:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>* * * * * date +\%Y\%m\%d_\%H\%M\%S &gt; /tmp/test</span></code></pre></td></tr></table></div></figure>


<p>happens to work the same if you copy it to a terminal because the %s are escaped in the cron line and the escaping will happen to drop off in shell as well, but what if you want a quoted % &ndash; you&rsquo;re stuffed.</p>

<p>Back to KISS again.</p>

<h2>Other reasons to keep cron simple</h2>

<p>If you&rsquo;re editing cron via <code>crontab -e</code> it&rsquo;s <a href="http://www.reddit.com/r/linuxadmin/comments/1pxvhv/crontab_r/">far too easy to wipe out your crontab file</a>.</p>

<p>While this is mostly an argument for backups, if you keep your cron files simple it <em>may</em> not matter as much <em>when</em> they get nuked accidentally as now you&rsquo;ve only lost scheduling information and not critical syntax :)</p>

<h2>Summary</h2>

<p>If I&rsquo;m not 100% certain I can copy a line out of cron and run it on the terminal I think it doesn&rsquo;t belong in cron.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Better XML support in PHP]]></title>
    <link href="http://blog.lyte.id.au//2013/04/27/better-xml-support-in-php/"/>
    <updated>2013-04-27T00:00:00+10:00</updated>
    <id>http://blog.lyte.id.au//2013/04/27/better-xml-support-in-php</id>
    <content type="html"><![CDATA[<p>XML support in PHP is actually pretty good these days, <a href="http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/">but as with anything in PHP</a> (why is that?) it has a few little quirks and corner cases that provide for continual facepalm moments.</p>

<p>Rather than just sit around and complain or try to get stuff in to the core (where there&rsquo;s no way I&rsquo;d be able to use it in real world projects until RHEL catches up, i.e. 3-4 years from now) I thought I&rsquo;d see what I could do purely in PHP.</p>

<p>Turns out it&rsquo;s quite a lot, so it&rsquo;s up on Github: <a href="https://github.com/neerolyte/php-lyte-xml#readme">https://github.com/neerolyte/php-lyte-xml#readme</a></p>

<p>So if you have to deal with the XML in PHP fairly often consider taking it for a spin.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[git stash that won't make you hate yourself in the morning]]></title>
    <link href="http://blog.lyte.id.au//2013/04/05/git-stash-that-won-make-you-hate-yourself-in-the-morning/"/>
    <updated>2013-04-05T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2013/04/05/git-stash-that-won-make-you-hate-yourself-in-the-morning</id>
    <content type="html"><![CDATA[<p>Git has a feature called stash that lets drop whatever you&rsquo;re working on and put the working directory back to a clean state without having to commit or lose whatever deltas you had.</p>

<p>This is a great idea, but it&rsquo;s sorely missing one core feature for anyone who works on more than one machine &ndash; the ability synchronise the stashes between machines, so if you&rsquo;re like me (I work on the same code on up to about 4 individual machines in a week) you probably want some way to move stashes around.</p>

<p>So I&rsquo;ve started <a href="https://github.com/neerolyte/git-rstash">git-rstash</a>, as usual it&rsquo;s written in terrible bash in the hope that someone will take enough offence at it to take the whole problem off my hands, in the mean time maybe you&rsquo;ll find it useful too.</p>

<p>For the moment synchronising them is purely up to the user, but they are conveniently placed where the user can drop them in whatever cloud-syncy-like thing they&rsquo;re already using (<a href="http://www.cis.upenn.edu/~bcpierce/unison/">Unison</a>, <a href="https://one.ubuntu.com/">Ubuntu One</a>, <a href="https://www.dropbox.com/">Dropbox</a>, etc).</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Too many ways to base64 in bash]]></title>
    <link href="http://blog.lyte.id.au//2013/03/19/too-many-ways-to-base64-in-bash/"/>
    <updated>2013-03-19T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2013/03/19/too-many-ways-to-base64-in-bash</id>
    <content type="html"><![CDATA[<p>I find myself writing little functions to to paste in to terminals to provide stream handlers quite often, like:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>base64_decode() {
</span><span class='line'>  php -r 'echo base64_decode(stream_get_contents(STDIN));'
</span><span class='line'>}
</span><span class='line'>base64_encode() {
</span><span class='line'>  php -r 'echo base64_encode(stream_get_contents(STDIN));'
</span><span class='line'>}</span></code></pre></td></tr></table></div></figure>


<p>Which can be used to encode or decode base64 strings in a stream, e.g.:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="nb">echo </span>foo | base64_encode
</span><span class='line'><span class="nv">Zm9vCg</span><span class="o">==</span>
</span><span class='line'><span class="nv">$ </span><span class="nb">echo </span><span class="nv">Zm9vCg</span><span class="o">==</span> | base64_decode
</span><span class='line'>foo
</span></code></pre></td></tr></table></div></figure>


<p>which is fun, but I wanted to make it a little more portable, so lets try a few more languages&hellip;</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c"># ruby</span>
</span><span class='line'>base64_encode<span class="o">()</span> <span class="o">{</span> ruby -e <span class="s1">&#39;require &#39;</span>base64<span class="s1">&#39;; puts Base64.encode64(ARGF.read)&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_decode<span class="o">()</span> <span class="o">{</span> ruby -e <span class="s1">&#39;require &#39;</span>base64<span class="s1">&#39;; puts Base64.decode64(ARGF.read)&#39;</span>; <span class="o">}</span>
</span><span class='line'><span class="c"># python</span>
</span><span class='line'>base64_encode<span class="o">()</span> <span class="o">{</span> python -c <span class="s1">&#39;import base64, sys; sys.stdout.write(base64.b64encode(sys.stdin.read()))&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_decode<span class="o">()</span> <span class="o">{</span> python -c <span class="s1">&#39;import base64, sys; sys.stdout.write(base64.b64decode(sys.stdin.read()))&#39;</span>; <span class="o">}</span>
</span><span class='line'><span class="c"># perl</span>
</span><span class='line'>base64_encode<span class="o">()</span> <span class="o">{</span> perl -e <span class="s1">&#39;use MIME::Base64; print encode_base64(&lt;STDIN&gt;);&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_decode<span class="o">()</span> <span class="o">{</span> perl -e <span class="s1">&#39;use MIME::Base64; print decode_base64(&lt;STDIN&gt;);&#39;</span>; <span class="o">}</span>
</span><span class='line'><span class="c"># openssl</span>
</span><span class='line'>base64_encode<span class="o">()</span> <span class="o">{</span> openssl enc -base64; <span class="o">}</span>
</span><span class='line'>base64_decode<span class="o">()</span> <span class="o">{</span> openssl enc -d -base64; <span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>and now to wrap them all under something that picks whichever seems to be available:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>base64_php<span class="o">()</span> <span class="o">{</span> php -r <span class="s1">&#39;echo base64_$1(stream_get_contents(STDIN));&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_ruby<span class="o">()</span> <span class="o">{</span> ruby -e <span class="s1">&#39;require &#39;</span>base64<span class="s1">&#39;; puts Base64.${1}64(ARGF.read)&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_perl<span class="o">()</span> <span class="o">{</span> perl -e <span class="s1">&#39;use MIME::Base64; print $1_base64(&lt;STDIN&gt;);&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_python<span class="o">()</span> <span class="o">{</span> python -c <span class="s1">&#39;import base64, sys; sys.stdout.write(base64.b64$1(sys.stdin.read()))&#39;</span>; <span class="o">}</span>
</span><span class='line'>base64_openssl<span class="o">()</span> <span class="o">{</span> openssl enc <span class="k">$(</span><span class="o">[[</span> <span class="nv">$1</span> <span class="o">==</span> encode <span class="o">]]</span> <span class="o">||</span> <span class="nb">echo</span> -d<span class="k">)</span> -base64; <span class="o">}</span>
</span><span class='line'>base64_choose<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>  <span class="k">for </span>lang in openssl perl python ruby php; <span class="k">do </span>
</span><span class='line'><span class="k">    if</span> <span class="o">[[</span> <span class="k">$(</span><span class="nb">type</span> -t <span class="s1">&#39;$lang&#39;</span><span class="k">)</span> <span class="o">==</span> <span class="s1">&#39;file&#39;</span> <span class="o">]]</span>; <span class="k">then</span>
</span><span class='line'>      <span class="s1">&#39;base64_$lang&#39;</span> <span class="s1">&#39;$1&#39;</span>
</span><span class='line'>      <span class="k">return</span>
</span><span class='line'><span class="k">    fi</span>
</span><span class='line'><span class="k">  done</span>
</span><span class='line'><span class="k">  </span><span class="nb">echo</span> <span class="s1">&#39;ERROR: No suitable language found&#39;</span>
</span><span class='line'>  <span class="k">return </span>1
</span><span class='line'><span class="o">}</span>
</span><span class='line'>base64_encode<span class="o">()</span> <span class="o">{</span> base64_choose encode; <span class="o">}</span>
</span><span class='line'>base64_decode<span class="o">()</span> <span class="o">{</span> base64_choose decode; <span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>great, now I can quickly grab some base64 commands on any box I&rsquo;m likely to be working on in the foreseeable future.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Applying settings to all Vagrant VMs]]></title>
    <link href="http://blog.lyte.id.au//2013/03/13/applying-settings-to-all-vagrant-vms/"/>
    <updated>2013-03-13T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2013/03/13/applying-settings-to-all-vagrant-vms</id>
    <content type="html"><![CDATA[<p>After upgrading from Ubuntu 12.04 (&ldquo;Precise Pangolin&rdquo;) to 12.10 (&ldquo;Quantal Quetzal&rdquo;) I lost the DNS resolver that VirtualBox normally provides on 10.0.2.3, meaning I couldn&rsquo;t boot my Vagrant VMs.</p>

<p>Finding an <a href="http://askubuntu.com/questions/238040/how-do-i-fix-name-service-for-vagrant-client">answer that worked around it for singular VMs</a>, I wanted something that worked for all VMs on the laptop (at least until I can fix the actually broken DNS resolver) and I&rsquo;ve found one.</p>

<p>As per <a href="http://docs-v1.vagrantup.com/v1/docs/vagrantfile.html">http://docs-v1.vagrantup.com/v1/docs/vagrantfile.html</a>, it&rsquo;s possible to specify additional parameters to Vagrant in ~/.vagrant.d/Vagrantfile &ndash; but it&rsquo;s not exactly clear how, turns out you can just place them in a normal config block like so:</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>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Vagrant::Config.run do |config|
</span><span class='line'>    config.vm.customize [&quot;modifyvm&quot;, :id, &quot;--natdnshostresolver1&quot;, &quot;on&quot;]
</span><span class='line'>end</span></code></pre></td></tr></table></div></figure>


<p>Before applying the fix I was getting hangs at &ldquo;Waiting for VM to boot&rdquo; like so:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ vagrant up
</span><span class='line'>[default] VM already created. Booting if it's not already running...
</span><span class='line'>[default] Clearing any previously set forwarded ports...
</span><span class='line'>[default] Forwarding ports...
</span><span class='line'>[default] -- 22 =&gt; 2222 (adapter 1)
</span><span class='line'>[default] Creating shared folders metadata...
</span><span class='line'>[default] Clearing any previously set network interfaces...
</span><span class='line'>[default] Preparing network interfaces based on configuration...
</span><span class='line'>[default] Booting VM...
</span><span class='line'>[default] Waiting for VM to boot. This can take a few minutes.</span></code></pre></td></tr></table></div></figure>


<p>after applying the fix, it continues on:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>...
</span><span class='line'>[default] Waiting for VM to boot. This can take a few minutes.
</span><span class='line'>[default] VM booted and ready for use!
</span><span class='line'>[default] Configuring and enabling network interfaces...
</span><span class='line'>[default] Setting host name...
</span><span class='line'>[default] Mounting shared folders...
</span><span class='line'>[default] -- v-root: /vagrant</span></code></pre></td></tr></table></div></figure>


<p>Edit: I just thought I&rsquo;d add that the config has changed slightly with Vagrant 1.1+, so you now need a &ldquo;v2 config block&rdquo; (see: <a href="http://docs.vagrantup.com/v2/virtualbox/configuration.html">http://docs.vagrantup.com/v2/virtualbox/configuration.html</a>):</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Vagrant::configure('2') do |config|
</span><span class='line'>  config.vm.provider &quot;virtualbox&quot; do |v|
</span><span class='line'>    v.customize [&quot;modifyvm&quot;, :id, &quot;--natdnshostresolver1&quot;, &quot;on&quot;]
</span><span class='line'>  end
</span><span class='line'>end</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Deleting an apt-snapshot btrfs subvolume is hard]]></title>
    <link href="http://blog.lyte.id.au//2013/03/08/deleting-an-apt-snapshot-btrfs-subvolume-is-hard/"/>
    <updated>2013-03-08T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2013/03/08/deleting-an-apt-snapshot-btrfs-subvolume-is-hard</id>
    <content type="html"><![CDATA[<p>This took me a while to figure out, so thought I&rsquo;d write up.</p>

<p>If for whatever reason a do-release-upgrade of Ubuntu fails part way through (say <a href="https://btrfs.wiki.kernel.org/index.php/Problem_FAQ#I_get_.22No_space_left_on_device.22_errors.2C_but_df_says_I.27ve_got_lots_of_space">because you&rsquo;ve used 75% of metadata and btrfs doesn&rsquo;t seem to fail gracefully</a>) and you&rsquo;ve got a working apt-snapshot, after you get everything back in order again it will have left behind a snapshot that you no longer want:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# btrfs subvol list /
</span><span class='line'>ID 256 top level 5 path @
</span><span class='line'>ID 257 top level 5 path @home
</span><span class='line'>ID 259 top level 5 path @apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28</span></code></pre></td></tr></table></div></figure>


<p>So you think to yourself, &ldquo;ok I can just delete it now&rdquo;:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# btrfs subvol delete @apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28
</span><span class='line'>ERROR: error accessing '@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28'
</span><span class='line'>root@foo:/# btrfs subvol delete /@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28
</span><span class='line'>ERROR: error accessing '/@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28'</span></code></pre></td></tr></table></div></figure>


<p>&hellip; hmm the obvious things don&rsquo;t work.</p>

<p>Turns out when a subvolume (in this case &ldquo;@&rdquo;) is mounted the snapshot subvolumes aren&rsquo;t mounted anywhere and you actually have to give a place where it&rsquo;s visible as a subvolume (not a direct mount).</p>

<p>Because that sentence made no sense, here&rsquo;s an example, this doesn&rsquo;t work:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:~# mkdir /@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28
</span><span class='line'>root@foo:~# mount -t btrfs -o subvol=@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28 /dev/mapper/foo-root /@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28
</span><span class='line'>root@foo:~# btrfs subvol delete @apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28
</span><span class='line'>ERROR: error accessing '@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28'</span></code></pre></td></tr></table></div></figure>


<p>because I&rsquo;ve mounted the subvolume I want to delete and I&rsquo;m giving the top of a FS to the subvolume delete command.</p>

<p>Instead, here&rsquo;s what does work (even with the FS already mounted on /), create somewhere to mount it:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# mkdir /mnt/tmp</span></code></pre></td></tr></table></div></figure>


<p>Mount it:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# mount /dev/mapper/foo-root /mnt/tmp</span></code></pre></td></tr></table></div></figure>


<p>Show that the subvolumes are all available as directories under the mount point:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# ls -l /mnt/tmp/
</span><span class='line'>total 0
</span><span class='line'>drwxr-xr-x 1 root root 292 Mar  8 10:26 @
</span><span class='line'>drwxr-xr-x 1 root root 240 Feb 21 08:31 @apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28
</span><span class='line'>drwxr-xr-x 1 root root  14 Mar  8 10:24 @home</span></code></pre></td></tr></table></div></figure>


<p>Delete it:</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'>root@foo:/# btrfs subvol delete /mnt/tmp/@apt-snapshot-release-upgrade-quantal-2013-03-07_21\:34\:28
</span><span class='line'>Delete subvolume '/mnt/tmp/@apt-snapshot-release-upgrade-quantal-2013-03-07_21:34:28'</span></code></pre></td></tr></table></div></figure>


<p>Hooray! It didn&rsquo;t error this time, it also actually worked:</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>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# btrfs subvol list /
</span><span class='line'>ID 256 top level 5 path @
</span><span class='line'>ID 257 top level 5 path @home</span></code></pre></td></tr></table></div></figure>


<p>Clean up:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@foo:/# umount /mnt/tmp</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[New and simplified license from Samsung Kies]]></title>
    <link href="http://blog.lyte.id.au//2013/03/05/new-and-simplified-license-from-samsung-kies/"/>
    <updated>2013-03-05T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2013/03/05/new-and-simplified-license-from-samsung-kies</id>
    <content type="html"><![CDATA[<p>I&rsquo;m sure something&rsquo;s wrong here, but can&rsquo;t quite put my finger on what&hellip;</p>

<p><a href="http://blog.lyte.id.au//wp-content/uploads/2013/03/kies.png"><img src="http://blog.lyte.id.au//wp-content/uploads/2013/03/kies.png" title="Blank license agreement from Kies" alt="Blank license agreement from Kies" /></a></p>

<p>&hellip; must be something to do with having to fire up a Windows VM to talk to a Linux based phone.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[VM Build Automation with Vagrant and VeeWee]]></title>
    <link href="http://blog.lyte.id.au//2012/10/02/vm-build-automation-with-vagrant-and-veewee/"/>
    <updated>2012-10-02T00:00:00+10:00</updated>
    <id>http://blog.lyte.id.au//2012/10/02/vm-build-automation-with-vagrant-and-veewee</id>
    <content type="html"><![CDATA[<p>So I&rsquo;ve finally done my second talk at a LUG (<a href="http://www.mlug.org.au/">Melbourne <strong>L</strong>inux <strong>U</strong>sers <strong>G</strong>roup</a> to be precise), I mainly put my hand up to do a talk because we were short this month and I wanted some practice. I decided to go the route of trying to generate a lot of discussion and demoing some of the stuff, rather than preparing and running through a linear set of slides. All in all, it seemed to go fairly well.</p>

<p>I decided to talk about <a href="http://vagrantup.com/" title="Vagrant">Vagrant</a> and <a href="https://github.com/jedi4ever/veewee">VeeWee</a>. I don&rsquo;t claim to be any kind of expert, but I have been tinkering and thought maybe I could stir a little more local interest in these types of automation tools.</p>

<h3>Audio</h3>

<p>Talk audio <a href="http://blog.lyte.id.au//mlug/MLUG_2012-10-02_David_Schoen_VM_Build_Automation.ogg">is available (50MB OGG)</a>.</p>

<p>For the most part the videos below were what was demoed during the talk, but there are some questions discussed during the talk that may be helpful (and some that simply will not make sense if you weren&rsquo;t there :p).</p>

<h3>Videos</h3>

<p>First up I go through  a standard Vagrant Init process, Vagrant is already installed but otherwise it just demos the minimum number of steps to get a VM up and running, then running something dubious from the internets and returning the system to a clean state.</p>

<iframe width="640" height="480" src="https://www.youtube.com/embed/Y2vR7UeCP3Y " frameborder="0" allowFullScreen></iframe>


<p>apt-cacher-ng demo &ndash; shows what should now be the standard steps for trialling something with Vagrant (git clone, vagrant up). In this case apt-cacher-ng, which can be used to speed up system building by caching repositories of various types when you are rebuilding similar machines quite often (<a href="https://github.com/neerolyte/mlug-vm-demos">https://github.com/neerolyte/mlug-vm-demos</a>):</p>

<iframe width="640" height="480" src="https://www.youtube.com/embed/W9nKyj7Kywo " frameborder="0" allowFullScreen></iframe>


<p>Spree Install &ndash; a nice complex rails app that grabs things off all sorts of places on the internet, sped up slight by using the apt-cacher-ng proxy above, but of course with Vagrant we still just &ldquo;vagrant up&rdquo; (<a href="https://github.com/neerolyte/mlug-vm-demos">https://github.com/neerolyte/mlug-vm-demos</a>):</p>

<iframe width="640" height="480" src="https://www.youtube.com/embed/lFrNRoLPsHk " frameborder="0" allowFullScreen></iframe>


<p>VeeWee build of a Vagrant basebox with a wrapper script (<a href="https://github.com/neerolyte/lyte-vagrant-boxes">https://github.com/neerolyte/lyte-vagrant-boxes</a>):</p>

<iframe width="640" height="480" src="https://www.youtube.com/embed/02bR8EOs32o " frameborder="0" allowFullScreen></iframe>


<h3>Resources</h3>

<ul>
<li>Vagrant: <a href="http://vagrantup.com/">http://vagrantup.com/</a></li>
<li>VeeWee: <a href="https://github.com/jedi4ever/veewee">https://github.com/jedi4ever/veewee</a></li>
<li>Vagrant Boxes: <a href="http://www.vagrantbox.es/">http://www.vagrantbox.es/</a></li>
<li>Mozilla blog article: <a href="http://blog.mozilla.org/webdev/2011/10/04/developing-with-vagrant-puppet-and-playdoh/">http://blog.mozilla.org/webdev/2011/10/04/developing-with-vagrant-puppet-and-playdoh/</a></li>
<li>My VeeWee basebox builder: <a href="https://github.com/neerolyte/lyte-vagrant-boxes">https://github.com/neerolyte/lyte-vagrant-boxes</a></li>
<li>My demo Vagrant specs: <a href="https://github.com/neerolyte/mlug-vm-demos">https://github.com/neerolyte/mlug-vm-demos</a></li>
<li>My Vagueant project (vaguely Vagrant for LXC): <a href="https://github.com/neerolyte/vagueant">https://github.com/neerolyte/vagueant</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dropping repoproxy development for apt-cacher-ng]]></title>
    <link href="http://blog.lyte.id.au//2012/06/03/dropping-repoproxy-development-for-apt-cacher-ng/"/>
    <updated>2012-06-03T00:00:00+10:00</updated>
    <id>http://blog.lyte.id.au//2012/06/03/dropping-repoproxy-development-for-apt-cacher-ng</id>
    <content type="html"><![CDATA[<p>Initially I started writing <a href="https://github.com/neerolyte/repoproxy" title="repoproxy">repoproxy</a> because I thought there were a bunch a of features I needed that simply couldn&rsquo;t be configured with apt-cacher-ng (ACNG), it turns out I was wrong.</p>

<p>The reasons I had (broadly) for starting repoproxy:</p>

<pre><code>- shared caches - multiple caches on a LAN, they should share some how

- CentOS - CentOS uses yum, how could it possibly be supported by ACNG?

- roaming clients - e.g. laptops that can't always sit behind the same static instance of ACNG

- NodeJS - I wanted to learn NodeJS, I've learnt a bit now and don't feel a huge desire to complete this project given I've figured out most of the other features neatly
</code></pre>

<p>Below I cover how to achieve all of the above features with ACNG as it really wasn&rsquo;t obvious to me so I suspect it might be useful to other too.</p>

<h2>Shared Caches</h2>

<p>I run a lot of VMs on my laptop, but also have other clients in the home and work networks that could benefit from having a shared repository cache. For me a good balance is having static ACNG servers at both home and work, but also having ACNG deployed to my laptop so that the the VMs can be updated, reimaged or get new packages without chewing through my mobile bandwidth.</p>

<p>This is actually natively supported with ACNG, it&rsquo;s just a matter of putting a proxy line in /etc/apt-cacher-ng/acng.conf like so:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Proxy: http://mirror.lyte:3142/</span></code></pre></td></tr></table></div></figure>


<p>Then it&rsquo;s just a matter of telling apt to use a localhost proxy anywhere that ACNG is installed:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">echo</span> <span class="s1">&#39;Acquire::http { Proxy &#39;</span>http://localhost:3142/<span class="s1">&#39;; };&#39;</span> &gt; /etc/apt/apt.conf.d/01proxy
</span></code></pre></td></tr></table></div></figure>


<p>This allows VMs on my laptop to have a portable repository cache when I&rsquo;m not on a normal network, but also allows me to benefit from cache others generate and vice versa.</p>

<p>I&rsquo;d like to at some point have trusted roaming clients (i.e. only my laptop) publish captured ACNG cache back to static ACNG cache servers. I&rsquo;m pretty sure I can achieve this using some if-up.d trickery combined with rsync, but I haven&rsquo;t tried yet.</p>

<p>I had considered trying to add something more generic to repoproxy that did a cache discovery and then possibly ICP (Internet Cache Protocol) to share cache objects between nodes on the same LAN, but there are some generalised security issues I can&rsquo;t come up with a good solution for, e.g. If my laptop is connected to a VPN and another node discovers it, how do I sensibly ensure they can&rsquo;t get anything via the VPN without making the configuration overly obtuse?</p>

<p>It seems like trying to implement self discovery would either involve a lot of excess configuration on participating nodes, or leave gaping security holes so for the moment I&rsquo;m keeping it simple.</p>

<h2>CentOS</h2>

<p>I use CentOS and Scientific Linux sometimes and I&rsquo;d like their repos to be cached too.</p>

<p>I had originally falsely assumed this would simply be impossible, but I read somewhere that there was at least a little support.</p>

<p>In my testing some things didn&rsquo;t work out of the box, but <a href="https://bugs.launchpad.net/ubuntu/+source/apt-cacher-ng/+bug/1006844">could be worked around</a>.</p>

<p>Essentially it seems like ACNG treats most files as one of volatile, persistent or force-cached and it&rsquo;s just a matter of relying on tweaking URL based regexs to understand any repositories you want to work with.</p>

<h2>Roaming Clients</h2>

<p>When I move my laptop between home and work or on to a public wifi point I want apt to &ldquo;just work&rdquo; I don&rsquo;t want to have to remember to alter some config each time I need it.</p>

<p>I found two methods described on <a href="https://help.ubuntu.com/community/Apt-Cacher-Server#A.22Roaming.22_mode">help.ubuntu.com</a> that were sort of on the right track, but running a cron every minute that insights network traffic when my network is mostly stable seems like a bad idea, as does having to reboot to gain the new settings (especially as Network Manager won&rsquo;t bring wireless up until after I login, so it wouldn&rsquo;t even work for my use case).</p>

<p>NB: I&rsquo;ve already gone back and added my event driven method to the help.ubuntu.com article.</p>

<p>I suspect it would be possible to utilise ACNG&rsquo;s <a href="http://www.unix-ag.uni-kl.de/~bloch/acng/html/howtos.html#howto-hooks">﻿﻿hook functionality</a>:</p>

<blockquote><p>8.9 How to execute commands before and after going online?
It is possible to configure custom commands which are executed before the internet connection attempt and after a certain period after closing the connection. The commands are bound to a remapping configuration and the config file is named after the name of that remapping config, like debrep.hooks for Remap-debrep. See section 4.3.2, conf/<em>.hooks and /usr/share/doc/apt-cacher-ng/examples/</em>.hooks files for details.</p></blockquote>

<p>I couldn&rsquo;t immediately bend this to my will, so I decided to go down a route I already understood.</p>

<p>I decided to use if-up.d to reset ACNG&rsquo;s config every time there was a new interface brought online, this allows for an event-driven update of the upstream proxy rather than relying on polling intermittently or a reboot of the laptop.</p>

<p>Create a new file /etc/network/if-up.d/apt-cacher-ng-reset-proxy and put the following script in it:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="c">#!/bin/bash</span>
</span><span class='line'>
</span><span class='line'><span class="c"># list of hosts that the proxy might be running on</span>
</span><span class='line'><span class="nv">hosts</span><span class="o">=(</span>
</span><span class='line'>        acng.on.my.home.network
</span><span class='line'>        acng.on.my.work.network
</span><span class='line'>        acng.at.my.friends.place
</span><span class='line'><span class="o">)</span>
</span><span class='line'>
</span><span class='line'>set_host<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>        <span class="nv">host</span><span class="o">=</span><span class="nv">$1</span>
</span><span class='line'>        <span class="nv">line</span><span class="o">=</span><span class="s1">&#39;Proxy: http://$host:3142/&#39;</span>
</span><span class='line'>        <span class="k">if</span> <span class="o">[[</span> -z <span class="nv">$host</span> <span class="o">]]</span>; <span class="k">then</span>
</span><span class='line'><span class="k">                </span><span class="nv">line</span><span class="o">=</span><span class="s1">&#39;# Proxy: disabled because none are contactable&#39;</span>
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'>
</span><span class='line'>        <span class="c"># adjust ACNG configuration to use supplied proxy</span>
</span><span class='line'>        sed -i -r <span class="s1">&#39;s%^\s*(#|)\s*Proxy: .*$%$line%g&#39;</span> <span class="se">\</span>
</span><span class='line'>                /etc/apt-cacher-ng/acng.conf
</span><span class='line'>
</span><span class='line'>        <span class="c"># if apt-cacher-ng is running</span>
</span><span class='line'>        <span class="k">if </span>service apt-cacher-ng status &gt; /dev/null 2&gt;&amp;1; <span class="k">then</span>
</span><span class='line'>                <span class="c"># restart it to take hold of new config</span>
</span><span class='line'>                service apt-cacher-ng restart
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'><span class="k">        </span><span class="nb">exit </span>0
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'>try_host<span class="o">()</span> <span class="o">{</span>
</span><span class='line'>        <span class="nv">host</span><span class="o">=</span><span class="nv">$1</span>
</span><span class='line'>        <span class="c"># if we can get to the supplied host</span>
</span><span class='line'>        <span class="k">if </span>ping -c 1 <span class="s1">&#39;$host&#39;</span> &gt; /dev/null 2&gt;&amp;1; <span class="k">then</span>
</span><span class='line'>                <span class="c"># tell ACNG to use it</span>
</span><span class='line'>                set_host <span class="s1">&#39;$host&#39;</span>
</span><span class='line'>        <span class="k">fi</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'><span class="c"># Run through all possible ACNG hosts trying them one at a time</span>
</span><span class='line'><span class="k">for </span>host in <span class="s1">&#39;${hosts[@]}&#39;</span>; <span class="k">do</span>
</span><span class='line'><span class="k">        </span>try_host <span class="s1">&#39;$host&#39;</span>
</span><span class='line'><span class="k">done</span>
</span><span class='line'>
</span><span class='line'><span class="c"># no proxies found, unset upstream proxy (i.e. we connect straight to the internet)</span>
</span><span class='line'>set_host
</span></code></pre></td></tr></table></div></figure>


<p>Make sure to adjust the script for your environment and make it executable with:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>chmod +x /etc/network/if-up.d/apt-cacher-ng-reset-proxy
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Moving my butter (btrfs)]]></title>
    <link href="http://blog.lyte.id.au//2012/03/21/moving-my-butter/"/>
    <updated>2012-03-21T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2012/03/21/moving-my-butter</id>
    <content type="html"><![CDATA[<p>I recently had need to migrate a btrfs mount to a new physical device and I wasn&rsquo;t immediately finding the answer with Google (shock horror!) so when I figured out the commands I thought I&rsquo;d share them here.</p>

<p>So uhm, before doing anything dangerous to a drive you&rsquo;ve taken a backup right?</p>

<p>Moving on&hellip;</p>

<p>I chose to use a process that let me do a live migration underneath the file system while there was still data being written to the file system&hellip; you know, for fun.</p>

<p>Adding in the new device is as simple as:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ btrfs device add $new_device $existing_mount_point</span></code></pre></td></tr></table></div></figure>


<p>Which is quick! Suddenly you have a whole bunch more data available.</p>

<p>Removing the old device takes a lot longer but the command is just as simple:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ btrfs device delete $old_device $existing_mount_point</span></code></pre></td></tr></table></div></figure>


<p>To get a vague idea of progress watch:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ btrfs-show
</span><span class='line'>Label: none  uuid: 05d0397c-2dfc-4c2b-a508-22bf23099776
</span><span class='line'>        Total devices 2 FS bytes used 682.24GB
</span><span class='line'>        devid    1 size 931.48GB used 688.29GB path /dev/sdb1
</span><span class='line'>        devid    2 size 1.82TB used 13.00GB path /dev/sdd
</span><span class='line'>
</span><span class='line'>Btrfs Btrfs v0.19</span></code></pre></td></tr></table></div></figure>


<p>In this case /dev/sdb1 is the old drive and /dev/sdd is the new drive. The usage of the new drive will gradually grow until it catches up with the old one. In the capture above it&rsquo;s about 19% (13.00GB / 688.29GB) complete.</p>

<p>Eventually when it completes /dev/sdb1 no longer shows in the device list:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ btrfs-show
</span><span class='line'>Label: none  uuid: 05d0397c-2dfc-4c2b-a508-22bf23099776
</span><span class='line'>        Total devices 1 FS bytes used 682.04GB
</span><span class='line'>        devid    2 size 1.82TB used 686.52GB path /dev/sdd
</span><span class='line'>
</span><span class='line'>Btrfs Btrfs v0.19</span></code></pre></td></tr></table></div></figure>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SSH Agent Forwarding is a Bug]]></title>
    <link href="http://blog.lyte.id.au//2012/03/19/ssh-agent-forwarding-is-a-bug/"/>
    <updated>2012-03-19T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2012/03/19/ssh-agent-forwarding-is-a-bug</id>
    <content type="html"><![CDATA[<p>At the very best Agent Forwarding is a feature that I want to make sure no one ever uses again&hellip; why?</p>

<p>It&rsquo;s dangerous &ndash; you&rsquo;re placing a socket that will happily answer cryptographic challenges that it shouldn&rsquo;t be in the hands of unknown parties.</p>

<p>It&rsquo;s only marginally easier than the alternative.</p>

<h2>So what is it?</h2>

<p>Well as usual the man page is fairly helpful here:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> -A      Enables forwarding of the authentication agent connection.  This can also
</span><span class='line'>         be specified on a per-host basis in a configuration file.
</span><span class='line'>
</span><span class='line'>         Agent forwarding should be enabled with caution.  Users with the ability
</span><span class='line'>         to bypass file permissions on the remote host (for the agent's
</span><span class='line'>         UNIX-domain socket) can access the local agent through the forwarded con‐
</span><span class='line'>         nection.  An attacker cannot obtain key material from the agent, however
</span><span class='line'>         they can perform operations on the keys that enable them to authenticate
</span><span class='line'>         using the identities loaded into the agent.</span></code></pre></td></tr></table></div></figure>


<p>The normal reason why you would want to forward your agent is because you&rsquo;re connecting to some server via some other server (usually because a direct connection isn&rsquo;t available).</p>

<p>The diagram below shows a fairly standard scenario where a DB server can&rsquo;t be accessed via the public internet, but can be indirectly accessed via the web server:
<img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/standard_ssh_agent_forwarding.png" title="Standard SSH Agent Forwarding" ></p>

<p>What a lot of people do at this point is forward their key with something like:</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>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>yourlaptop$ ssh -A you@webserver
</span><span class='line'>webserver$ ssh you@dbserver
</span><span class='line'>dbserver$</span></code></pre></td></tr></table></div></figure>


<p>Which is relatively simple (and can be simplified more so by turning on authentication agent forwarding in ssh_config), but it&rsquo;s terrible unless you completely trust the security of your web server (please don&rsquo;t do that).</p>

<p>Lets look at why it&rsquo;s so terrible:</p>

<ol>
<li>Anyone else with sufficient access to the web server can use your forwarded agent to authenticate to anything you have access to.</li>
<li>Most web servers have known vulnerabilities that you probably haven&rsquo;t patched for yet.</li>
<li>1 + 2 = terrible</li>
</ol>


<p>To be clear I&rsquo;m not saying that we&rsquo;re forwarding actual bits of key material to an untrustworthy host, just that we&rsquo;re forwarding a connection to an agent that is able to answer authentication challenges to another host you may have access to. In practice one way attackers might use this is if they can see the environment variables your SSH connection came in via (either they have gained access to your account or root) then they could interrogate the SSH_AUTH_SOCK environment variable, add that in to their own environment and use your authentication agent to initiate authenticated connections to other hosts while you are still connected to the untrustworthy host.</p>

<h2>So what&rsquo;s the alternative?</h2>

<p>ProxyCommand + nc.</p>

<p>ProxyCommand is a (seemingly little known) directive you can give to SSH to say &ldquo;hey before you connect to where I&rsquo;ve told you to, fire up a socket to something arbitrary first&rdquo;. &ldquo;nc&rdquo; (or netcat) is something to give you an arbitrary connection.</p>

<p>Here&rsquo;s an example (continuing on from above):</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'>yourlaptop$ ssh -o 'ProxyCommand ssh you@webserver nc %h %p' you@dbserver
</span><span class='line'>dbserver$</span></code></pre></td></tr></table></div></figure>


<p>What this does is connects to webserver, authenticates using your key as you and then runs &ldquo;nc&rdquo; replacing in the hostname and port for the dbserver as it does. This will return a socket (running over the encrypted SSH connection) that can connect directly to the dbserver. SSH will then connect to the socket as you and authenticate with your key, but note that the encryption between you and the dbserver is end-to-end so you don&rsquo;t need to make your authentication agent available in any potentially untrustworthy environments.</p>

<h2>Ok that&rsquo;s great and all but it&rsquo;s too much to type</h2>

<p>Put it in your ~/.ssh/config file, for the example above something like this should work:</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'>Host dbserver
</span><span class='line'>ProxyCommand ssh you@webserver nc %h %p</span></code></pre></td></tr></table></div></figure>


<p>Once that&rsquo;s in place you can just run:</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'>yourlaptop$ ssh you$dbserver
</span><span class='line'>dbserver$</span></code></pre></td></tr></table></div></figure>


<h2>What about a range of hosts?</h2>

<p>The only real thing to watch out for here is that if you match a range of hosts and the host you&rsquo;re routing via is in that matched range, SSH will quite happily fork bomb your machine:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># Be very careful to disable ProxyCommand on the host you are routing via or you will fork bomb yourself.
</span><span class='line'>Host gateway.difficult.to.get.to
</span><span class='line'>ProxyCommand none
</span><span class='line'>Host *.difficult.to.get.to
</span><span class='line'>ProxyCommand ssh you@gateway.difficult.to.get.to nc %h %p</span></code></pre></td></tr></table></div></figure>


<h2>What if I have to jump via multiple hosts?</h2>

<p>Well firstly, redesign your network.</p>

<p>If for some reason that&rsquo;s not a realistic option, you can just stack hops together:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Host hop2
</span><span class='line'>ProxyCommand ssh you@hop1 nc %h %p
</span><span class='line'>Host hop3
</span><span class='line'>ProxyCommand ssh you@hop2 nc %h %p
</span><span class='line'>Host hop4
</span><span class='line'>ProxyCommand ssh you@hop3 nc %h %p
</span><span class='line'>...</span></code></pre></td></tr></table></div></figure>


<h2>But it&rsquo;s so slow&hellip;</h2>

<p>In some circumstances doing this can be slower (e.g. when you spend all your time connected to an intermediate server connecting to other servers). This is because you&rsquo;re now firing up multiple SSH connections each time you make a new connection instead of just one.</p>

<p>One pretty common work around for this is:</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>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ControlMaster auto
</span><span class='line'>ControlPath /home/you/.ssh/master-%r@%h:%p
</span><span class='line'>ControlPersist yes</span></code></pre></td></tr></table></div></figure>


<p>Run &ldquo;man ssh_config&rdquo; and search for &ldquo;ControlMaster&rdquo; to read up in more detail about this.</p>

<p>The TL;DR of it is &ndash; ControlMaster creates multiplexing magic to convert multiple connections down to one (meaning much less build-up / tear-down lag).</p>

<h2>Similarity to onion routing</h2>

<p>Using ssh like this is very similar to <a href="http://en.wikipedia.org/wiki/Onion_routing" title="Onion Routing">onion routing</a> in that you have end-to-end encryption (and authentication!) by only trusting each mid-point to run up a socket (courtesy of netcat) for you. However please don&rsquo;t assume that because the encryption going on here is similar to TOR that you can use it to alleviate the privacy concerns that TOR does.</p>

<p>Update: clarified that the agent and not the key is being forwarded, also explained a little more depth what that means.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[My Falco's Suicidal Side Stand]]></title>
    <link href="http://blog.lyte.id.au//2012/03/16/my-falcos-suicidal-side-stand/"/>
    <updated>2012-03-16T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2012/03/16/my-falcos-suicidal-side-stand</id>
    <content type="html"><![CDATA[<p>Once upon a time I baught a Falco</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_20110326_151143-600x448.jpg" title="IMG_20110326_151143" alt="" /></p>

<p>It took me to see a waterfall</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_1280-600x450.jpg" title="IMG_1280" alt="" /></p>

<p>in Toora</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_1289-600x450.jpg" title="IMG_1289" alt="" /></p>

<p>I parked it against a tree</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_1291-600x450.jpg" title="IMG_1291" alt="" /></p>

<p>I spotted windmills</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_1284-600x450.jpg" title="IMG_1284" alt="" /></p>

<p>and it took me there too</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_1274-600x450.jpg" title="IMG_1274" alt="" /></p>

<p>I parked it against a dumpster</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_1272-450x600.jpg" title="IMG_1272" alt="" /></p>

<p>I went to see a friend</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_20110905_113348-600x448.jpg" title="IMG_20110905_113348" alt="" /></p>

<p>I parked it against a pole</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_20110904_141208-448x600.jpg" title="IMG_20110904_141208" alt="" /></p>

<p>I went home and parked it against that too</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_20110729_114351-448x600.jpg" title="IMG_20110729_114351" alt="" /></p>

<p>I don&rsquo;t understand why Aprilia would make such a great bike and then almost ruin it by putting far too much of it on the wrong side of the stand&hellip; but they did</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_20111104_143648-448x600.jpg" title="IMG_20111104_143648" alt="" /></p>

<p>fortunately I made mine a hybrid and now it <em><strong>stands</strong></em> on its own</p>

<p><img src="http://blog.lyte.id.au//wp-content/uploads/2012/03/IMG_20111104_153413-448x600.jpg" title="IMG_20111104_153413" alt="" /></p>

<p>Yeh, that&rsquo;s my story.</p>

<p>P.s. for those who actually want technical information&hellip;</p>

<p>I swapped out the stock stand for one off a Honda CBR 1100 Blackbird. If you attempt this be prepared to completely and utterly disable the side stand kill switch.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Brief Look in to Exploiting Binaries on Modern Linux]]></title>
    <link href="http://blog.lyte.id.au//2012/03/03/a-brief-look-in-to-exploiting-binaries-on-modern-linux/"/>
    <updated>2012-03-03T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2012/03/03/a-brief-look-in-to-exploiting-binaries-on-modern-linux</id>
    <content type="html"><![CDATA[<p>Recently I&rsquo;ve decided to start poking and prodding some security related CTFs (Capture The Flags).</p>

<p>Mainly I worked on <a href="https://stripe.com/blog/capture-the-flag">the Stripe CTF</a> (now closed) and I&rsquo;m playing with <a href="http://io.smashthestack.org:84/">Smash the Stack&rsquo;s IO</a>.</p>

<p>I&rsquo;ve already learnt a few things along the way that I thought would have been useful to me in a cheat sheet like form, so here it is&hellip;</p>

<p><strong>GCC</strong></p>

<p>When compiling little snippets of C locally on my laptop I&rsquo;ve found that quite often I&rsquo;ve had to turn off a fair bit of protection to get the snippets to compile in just the right way.</p>

<p>To get 32 bit binaries (CTFs so far have been 32bit):
<code>$ gcc -m32 ...</code>
Note: you may need to install gcc-multilib on Ubuntu.</p>

<p>To turn off stack protection (are these canary values?):
<code>$ gcc -fno-stack-protector ...</code></p>

<p>To enable debugging symbols for use with GDB:
<code>$ gcc -ggdb ...</code></p>

<p>Normally GCC will produce binaries with stacks that are not executable, to enable executable stacks:
<code>$ execstack -s %binary_created_with_gcc%</code></p>

<p><strong>Shellcode</strong></p>

<p>Once you&rsquo;ve figured out what shellcode is and why you need it, you&rsquo;ll still need some way to store it in a string (probably a program argument), here&rsquo;s the two main methods I&rsquo;ve been using.</p>

<p>Using perl (seems to be a favourite amongst the community):
<code>$ /some/binary "$(perl -e 'printf "\x90" x 100')"</code></p>

<p>Straight from bash:
<code>$ /some/binary $'\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90'</code></p>

<p><strong>objdump</strong>
Figuring out a binaries format:
<code>$ objdump -t /foo/bar | grep 'file format'
/foo/bar: file format elf32-i386</code></p>

<p>Getting the address of &ldquo;main&rdquo; from the symbol table:
<code>$ objdump -t /foo/bar | grep main
080483b4 g F .text 00000067 main</code></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ruxcon 2011]]></title>
    <link href="http://blog.lyte.id.au//2011/11/21/ruxcon-2011/"/>
    <updated>2011-11-21T00:00:00+11:00</updated>
    <id>http://blog.lyte.id.au//2011/11/21/ruxcon-2011</id>
    <content type="html"><![CDATA[<p>My head&rsquo;s just now starting to recover from 4 days of <a href="http://ruxcon.org.au">Ruxcon</a>. 2 days training, 2 days conference, plus a lot of <del datetime="2011-11-20T20:43:50+00:00">partying</del> networking.</p>

<p>It&rsquo;s the first properly security related thing I&rsquo;ve ever been to, but I was amazed just how quickly I was able to catch on to many of the modern techniques being used to pen test systems out in the wild right now. I don&rsquo;t think it&rsquo;s because I&rsquo;m super smart, I think it&rsquo;s because most of the flaws that are exploitable are super obvious and you really only need <strong>one</strong> piece of broken logic to get in to somewhere you don&rsquo;t belong. It was also quite impressive just how creatively a lot of the people there were able to look at 2 or 3 relatively minor bugs and escalate them in to a full system access hack.</p>

<p>Pen testing also isn&rsquo;t all the low level buffer over flow stuff I was expecting either, sure there are guys there that can do that and other much fancier stuff to get out of buffer overflow, smash your stack and completely own your box, but there&rsquo;s still the good ol&#8217; &ldquo;hmm that acl doesn&rsquo;t look quite right&rdquo;.</p>

<p>I managed to catch both talks by Adam and James from <a href="http://www.insomniasec.com/">Insomnia</a>, what was impressed on me most was that I understood almost everything these guys were doing. Further more a lot of what James was talking about to escalate privileges in a Windows environment was stuff that I was tinkering (sometimes a little too successfully with) back at high school :/</p>

<p>Another pretty interesting stream is just how prolific SQL injection is. I thought (before Thursday) that parameterised SQL queries had solved all the injection problems and the world of IT Security had moved on to harder targets. Turns out I was wrong. This seems to be mainly because half of programmers out there still haven&rsquo;t actually heard about SQL injection :( It&rsquo;s compounded by the fact that those that have probably don&rsquo;t realise just how easy tools like <a href="http://sqlmap.sourceforge.net/">sqlmap</a> make it. With sqlmap you can take a blind SQLi (SQL injection) attack and have it fire up a SQL prompt for you that lets you write arbitrary select queries, or dump the DB to CSV&hellip; wow. Better yet, even parameterised SQL normally can&rsquo;t parameterise the fields in the &ldquo;ORDER BY&rdquo; so a lot of programmers will be utilising parameterised SQL thinking it makes them completely safe, when in fact they&rsquo;ve just made it fractionally harder.</p>

<p>There was way too much other cool stuff to talk about, I&rsquo;m definitely going to try and go again next year.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Subversion my home directory]]></title>
    <link href="http://blog.lyte.id.au//2011/09/22/subversion-my-home-directory/"/>
    <updated>2011-09-22T00:00:00+10:00</updated>
    <id>http://blog.lyte.id.au//2011/09/22/subversion-my-home-directory</id>
    <content type="html"><![CDATA[<p>Every now and then I see someone asking about an alternative to using Dropbox to manage their dot files in their home directory.</p>

<p>A fair while ago (at least 2 years) I started using Subversion to do this. At some point I wrote a script that can be put in my user&rsquo;s cron file to automate updates and commits.</p>

<p>I figured I would finally publish it so that others can use or improve (or simply abuse) it.</p>

<p>I also decided to finally set up a github account, so it can be found there <a href="https://github.com/neerolyte/scripts/blob/master/subversion_auto_sync">there</a>.</p>

<p>To use it I put lines like this in &ldquo;crontab -e&rdquo;:</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'># pidgin - 1 day of lag ok
</span><span class='line'>49 */2 * * * . /home/foo/.ssh/agent; /home/foo/path/to/subversion_auto_sync --max-lag=$((24*60*60)) /home/foo/.purple</span></code></pre></td></tr></table></div></figure>


<p>Which every 2 hours runs subversion_auto_sync on my home directory with my ssh-agent environment loaded to allow automated (but secure) key based authentication. This example will not run an update for up to 24 hours since the last update, but it will always commit if local modifications have occurred. This provides gradual synchronisation of my Pidgin logs between all Desktops/Laptops I use.</p>

<p>I&rsquo;ve got the vast bulk of my important home directory files either in Subversion using something similar to what&rsquo;s above, or being synchronised with <a href="http://www.cis.upenn.edu/~bcpierce/unison/">Unison</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Oops I needed that partition table...]]></title>
    <link href="http://blog.lyte.id.au//2011/08/15/oops-i-needed-that-partition-table/"/>
    <updated>2011-08-15T00:00:00+10:00</updated>
    <id>http://blog.lyte.id.au//2011/08/15/oops-i-needed-that-partition-table</id>
    <content type="html"><![CDATA[<p>I just lost the partition table on a drive with a non-standard layout and managed to get the data back&hellip; phew.</p>

<p>I originally had something like:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>   Device Boot      Start         End      Blocks   Id  System
</span><span class='line'>/dev/sda1   *           1          26      208813+  83  Linux
</span><span class='line'>/dev/sda2              27        3943    31463302+  8e  Linux LVM
</span><span class='line'>/dev/sda3            3944        5221    10265535    7  HPFS/NTFS</span></code></pre></td></tr></table></div></figure>


<p>Note: partition table above is from a VM I spun up to write this entry.</p>

<p>That is to say I had a drive dual booting Linux and Windows, with Windows at the end of drive (<a href="http://www.coker.com.au/bonnie++/" title="because Russel sort of implied it was better">because Russel sort of implied it was better</a>).</p>

<p>The person who owns the drive in question wanted all the space claimed by Linux reallocated back to Windows.</p>

<p>After confirming backups of critical documents I fired up gparted in a live CD&hellip; which all seems swimmingly ok until the Laptop powered off (because the power plug had dropped out and the battery went flat).</p>

<p>After trying to boot up I discovered a corrupted partition table.</p>

<p>This would probably be ok (given the backups of documents) if not for the fact that I had no appropriate Windows installation media and the owner of the Laptop couldn&rsquo;t find the original installation disks.</p>

<p>Oh noes! (I scream loudly inside my head so as not to alarm the owner of the Laptop)</p>

<p>After booting back in to the live CD I have a partition table that looks more like this:</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>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>   Device Boot      Start         End      Blocks   Id  System
</span><span class='line'>/dev/sda1   *           1          26      208813+  83  Linux
</span><span class='line'>/dev/sda3              27        1304    10265535    7  HPFS/NTFS</span></code></pre></td></tr></table></div></figure>


<p>&ldquo;Ok&rdquo; I hear you saying &ldquo;just rewrite the partition table with the output you saved from &#8220;fdisk -l&rdquo; before starting. &ldquo;Oh you didn&rsquo;t save the output before starting&hellip;&rdquo;</p>

<p>After a bit of hair pulling (and googling) I come across <a href="http://www.brzitwa.de/mb/gpart/">gpart</a>.</p>

<p>It found the old partition without breaking a sweat:</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>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@ubuntu:~# gpart /dev/sda
</span><span class='line'>
</span><span class='line'>Begin scan...
</span><span class='line'>Possible partition(Linux ext2), size(203mb), offset(0mb)
</span><span class='line'>Possible partition(Windows NT/W2K FS), size(10024mb), offset(203mb)
</span><span class='line'>Possible partition(Windows NT/W2K FS), size(10024mb), offset(30929mb)
</span><span class='line'>End scan.
</span><span class='line'>[...]
</span><span class='line'>Primary partition(3)
</span><span class='line'>   type: 007(0x07)(OS/2 HPFS, NTFS, QNX or Advanced UNIX)
</span><span class='line'>   size: 10024mb #s(20531070) s(63344295-83875364)
</span><span class='line'>   chs:  (1023/254/63)-(1023/254/63)d (3943/0/1)-(5220/254/63)r
</span><span class='line'>[...]</span></code></pre></td></tr></table></div></figure>


<p>After talking to fdisk nicely I was able to convince it to create the partition table that gpart was suggesting and subsequently able to mount, resize properly and validate the partition with Windows chkdsk tool&hellip; phew, crisis averted.</p>

<p>Next time I&rsquo;m dding the disk to a USB drive first, no matter how long it takes.</p>
]]></content>
  </entry>
  
</feed>
