<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>n8blog &#187; Hacking</title>
	<atom:link href="http://www.n8gray.org/blog/category/hacking/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.n8gray.org</link>
	<description>distraction in action</description>
	<lastBuildDate>Thu, 01 Jul 2010 18:21:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Paucity of Code</title>
		<link>http://www.n8gray.org/blog/2010/06/14/a-paucity-of-code/</link>
		<comments>http://www.n8gray.org/blog/2010/06/14/a-paucity-of-code/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 01:13:28 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Hacking]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/?p=293</guid>
		<description><![CDATA[I just installed a plugin to do syntax highlighting on the code blocks in my blog, so naturally I went looking through my posts for code blocks to admire.  I was shocked to find that I haven&#8217;t shared much code at all!  I&#8217;ll have to change that.  Stay tuned&#8230;]]></description>
			<content:encoded><![CDATA[<p>I just installed a plugin to do syntax highlighting on the code blocks in my blog, so naturally I went looking through my posts for code blocks to admire.  I was shocked to find that I haven&#8217;t shared much code at all!  I&#8217;ll have to change that.  Stay tuned&#8230;</p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2010%2F06%2F14%2Fa-paucity-of-code%2F&amp;linkname=A%20Paucity%20of%20Code"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2010/06/14/a-paucity-of-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Simple Facebook Session Proxy for Google App Engine</title>
		<link>http://www.n8gray.org/blog/2010/06/09/a-simple-facebook-session-proxy-for-google-app-engine/</link>
		<comments>http://www.n8gray.org/blog/2010/06/09/a-simple-facebook-session-proxy-for-google-app-engine/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 18:53:35 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[HexaLex]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/?p=268</guid>
		<description><![CDATA[If you&#8217;re building an iPhone app that uses Facebook Connect you&#8217;re eventually going to need a session proxy.  The session proxy acts as a middleman between your iPhone app and Facebook&#8217;s servers, so that you don&#8217;t have to distribute your Facebook app secret with your app, where it can easily be extracted by someone [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re building an iPhone app that uses Facebook Connect you&#8217;re eventually going to need a session proxy.  The session proxy acts as a middleman between your iPhone app and Facebook&#8217;s servers, so that you don&#8217;t have to distribute your Facebook app secret with your app, where it can easily be extracted by someone knowledgeable with a hex editor.<br />
<span id="more-268"></span></p>

<p>Before I start, I should address the inevitable &#8220;what about OAuth2&#8243; comments.  Yes, OAuth2 is the new hotness for Facebook authentication, but the Facebook Connect iPhone <span class="caps">SDK </span>isn&#8217;t going to get broken (intentionally!) any time soon.  (I have that on authority from a friend inside Facebook, <span class="caps">BTW.</span>)  If you&#8217;ve got the time to replicate the functionality of <span class="caps">FBC</span>onnect for the new world order I salute you, but otherwise this code may come in handy and will continue to function until a full-featured replacement for <span class="caps">FBC</span>onnect arrives.</p>

<p>With a session proxy (say at http://your-server.example.com/fbproxy), this is how the client establishes a session:</p>


<ul>
<li>Phone:  <br />
   &#8211; <span class="caps">GET </span>http://your-server.example.com/fbproxy?auth_token=A_TOKEN&#038;&#8230;</li>
<li>To respond, your server relays the results of this <span class="caps">POST</span>: <br />
   &#8211; <span class="caps">POST</span>: http://api.facebook/com/restserver.php<br />
   &#8211; <span class="caps">POST </span>body: auth_token=A_TOKEN&#038;sig=A_SIGNATURE&#038;&#8230;</li>
</ul>



<p>A_SIGNATURE is generated using your FB app secret, so Facebook knows the request is legit.  Facebook returns a session key &#038; secret that can be used to make Facebook <span class="caps">API </span>calls from the phone.  If you&#8217;re wondering (like I did) how this is any more secure than shipping your app secret directly, you should understand that a session key is much less powerful than an app secret.  The app secret is basically the root password for your app, while a session key gets you an unprivileged user account.</p>

<p>With HexaLex I&#8217;ve used Google App Engine to host most of the backend service, so I ended up adapting some sample code I found online to do the job.  (<a href="http://code.google.com/p/minifb/">minifb</a> is particularly readable.)  I didn&#8217;t want to pull in a bunch of other dependencies, so this code is self-sufficient.  I&#8217;m using Google&#8217;s webapp framework so that&#8217;s what&#8217;s used in the code, but it should be easy to adapt to whatever framework you favor.  Without further ado, here&#8217;s the code:</p>


<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">&quot;&quot;&quot;
To use this, write in your Facebook API key and secret below and then
add FacebookSessionProxy to your list of url handlers:
    application = webapp.WSGIApplication(
        [('/fbproxy', FacebookSessionProxy),
         ...])
&nbsp;
Then in your iPhone code use something like
session = [FBSession sessionForApplication:myApiKey 
             getSessionProxy:@&quot;http://yourApp.appspot.com/fbproxy&quot;
             delegate:self];
&quot;&quot;&quot;</span>
<span style="color: #ff7700;font-weight:bold;">import</span> hashlib
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">httplib</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib</span>
<span style="color: #ff7700;font-weight:bold;">from</span> google.<span style="color: black;">appengine</span>.<span style="color: black;">ext</span> <span style="color: #ff7700;font-weight:bold;">import</span> webapp
&nbsp;
<span style="color: #808080; font-style: italic;"># This lambda prevents the secret from appearing in cgitb backtraces</span>
FB_API_SECRET = <span style="color: #ff7700;font-weight:bold;">lambda</span>:<span style="color: #483d8b;">&quot;YOUR_API_SECRET&quot;</span>
FB_API_KEY = <span style="color: #483d8b;">&quot;YOUR_API_KEY&quot;</span>
&nbsp;
FB_API_HOST=<span style="color: #483d8b;">&quot;api.facebook.com&quot;</span>
FB_API_PATH=<span style="color: #483d8b;">&quot;/restserver.php&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> facebook_signature<span style="color: black;">&#40;</span>paramsDict<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Compute the signature of a Facebook request&quot;&quot;&quot;</span>
    <span style="color: #008000;">sorted</span> = paramsDict.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #008000;">sorted</span>.<span style="color: black;">sort</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    trace = <span style="color: #483d8b;">''</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;%s=%s&quot;</span> <span style="color: #66cc66;">%</span> x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">sorted</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
    trace += FB_API_SECRET<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #dc143c;">md5</span> = hashlib.<span style="color: #dc143c;">md5</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #dc143c;">md5</span>.<span style="color: black;">update</span><span style="color: black;">&#40;</span>trace<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">md5</span>.<span style="color: black;">hexdigest</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_fb_session<span style="color: black;">&#40;</span>auth_token<span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;Request a Facebook session using the given auth_token&quot;&quot;&quot;</span>
    params=<span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">&quot;api_key&quot;</span>:FB_API_KEY,
            <span style="color: #483d8b;">&quot;v&quot;</span>:<span style="color: #483d8b;">&quot;1.0&quot;</span>,
            <span style="color: #483d8b;">&quot;auth_token&quot;</span>:auth_token,
            <span style="color: #483d8b;">&quot;generate_session_secret&quot;</span>:<span style="color: #483d8b;">&quot;1&quot;</span>,
            <span style="color: #483d8b;">&quot;method&quot;</span>:<span style="color: #483d8b;">&quot;auth.getSession&quot;</span>,
    <span style="color: black;">&#125;</span>
    params<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;sig&quot;</span><span style="color: black;">&#93;</span> = facebook_signature<span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>
&nbsp;
    encoded_params = <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlencode</span><span style="color: black;">&#40;</span>params<span style="color: black;">&#41;</span>
    headers = <span style="color: black;">&#123;</span>
            <span style="color: #483d8b;">&quot;Content-type&quot;</span>:<span style="color: #483d8b;">&quot;application/x-www-form-urlencoded&quot;</span>,
    <span style="color: black;">&#125;</span>
&nbsp;
    conn = <span style="color: #dc143c;">httplib</span>.<span style="color: black;">HTTPConnection</span><span style="color: black;">&#40;</span>FB_API_HOST<span style="color: black;">&#41;</span>
    conn.<span style="color: black;">request</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;POST&quot;</span>, FB_API_PATH, encoded_params, headers<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> conn.<span style="color: black;">getresponse</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> FacebookSessionProxy<span style="color: black;">&#40;</span>webapp.<span style="color: black;">RequestHandler</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> get<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        response = <span style="color: #008000;">self</span>.<span style="color: black;">response</span>
        auth_token = <span style="color: #008000;">self</span>.<span style="color: black;">request</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'auth_token'</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>auth_token<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>:
            response.<span style="color: black;">set_status</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">httplib</span>.<span style="color: black;">BAD_REQUEST</span><span style="color: black;">&#41;</span>
            response.<span style="color: black;">out</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Facebook login error: no auth_token given.&quot;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">return</span>
        fbResponse = get_fb_session<span style="color: black;">&#40;</span>auth_token<span style="color: black;">&#41;</span>
        response.<span style="color: black;">out</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span>fbResponse.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        response.<span style="color: black;">set_status</span><span style="color: black;">&#40;</span>fbResponse.<span style="color: black;">status</span>, fbResponse.<span style="color: black;">reason</span><span style="color: black;">&#41;</span>
        response.<span style="color: black;">headers</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'Content-Type'</span><span style="color: black;">&#93;</span> = fbResponse.<span style="color: black;">getheader</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'content-type'</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># The End</span></pre></div></div>




<p><strong>Update</strong>: I fixed a bug in the call to get_fb_session.  Thanks to Justin Williams for reporting it.</p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2010%2F06%2F09%2Fa-simple-facebook-session-proxy-for-google-app-engine%2F&amp;linkname=A%20Simple%20Facebook%20Session%20Proxy%20for%20Google%20App%20Engine"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2010/06/09/a-simple-facebook-session-proxy-for-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WTF is MIPSEL?</title>
		<link>http://www.n8gray.org/blog/2008/05/25/wtf-is-mipsel/</link>
		<comments>http://www.n8gray.org/blog/2008/05/25/wtf-is-mipsel/#comments</comments>
		<pubDate>Sun, 25 May 2008 20:16:22 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/?p=171</guid>
		<description><![CDATA[My Popcorn Hour PCH A-100 media streamer has a mipsel architecture, which led me to wonder, &#8220;what the heck does mipsel mean anyway?&#8221;  As it turns out, the difference between mips and mipsel is that mips is big-endian and mipsel is little-endian.  Mystery solved.]]></description>
			<content:encoded><![CDATA[<p>My <a href="http://www.popcornhour.com/onlinestore/">Popcorn Hour <span class="caps">PCH</span> A-100 media streamer</a> has a mipsel architecture, which led me to wonder, &#8220;what the heck does mipsel mean anyway?&#8221;  As it turns out, the difference between mips and mipsel is that mips is big-endian and mipsel is little-endian.  Mystery solved.</p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2008%2F05%2F25%2Fwtf-is-mipsel%2F&amp;linkname=WTF%20is%20MIPSEL%3F"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2008/05/25/wtf-is-mipsel/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dictionary attacks, or why log file monitoring is dumb</title>
		<link>http://www.n8gray.org/blog/2008/01/28/dictionary-attacks-or-why-log-file-monitoring-is-dumb/</link>
		<comments>http://www.n8gray.org/blog/2008/01/28/dictionary-attacks-or-why-log-file-monitoring-is-dumb/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 00:59:59 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/blog/2008/01/28/dictionary-attacks-or-why-log-file-monitoring-is-dumb/</guid>
		<description><![CDATA[Like most ssh servers on the internet, the Mojave group server gets lots of ssh dictionary attack attempts.  These attacks are carried out by scripts that try to find dumb passwords on a machine by brute force.  There are a few different tactics these scripts use for picking username/password pairs, including:



User: root, Password: [...]]]></description>
			<content:encoded><![CDATA[<p>Like most ssh servers on the internet, the Mojave group server gets lots of ssh dictionary attack attempts.  These attacks are carried out by scripts that try to find dumb passwords on a machine by brute force.  There are a few different tactics these scripts use for picking username/password pairs, including:</p>


<ul>
<li>User: root, Password: aardvark.  (Repeat with various well-known usernames and every word in the English dictionary)</li>
<li>User: abe, Password: abe.  (Repeat with all common first/last names)</li>
</ul>



<p>It&#8217;s not hard to think of simple methods to cut off these attacks without altering or otherwise restricting one&#8217;s ssh service (by, say, running sshd on a non-standard port):  </p>


<ul>
<li>Throttle login attempts on a per-host basis.  i.e. if a host tries and fails to log in N times in M seconds then start making it wait longer and longer between successive logins (or even blacklist the host entirely).</li>
<li>Throttle login attempts on a per-account basis.  i.e. if user bob gets N failed login attempts within M seconds then throttle or blacklist future login attempts on that account.</li>
<li>Auto-blacklist hosts that attempt to log in to accounts that should never be logged in to.  e.g. if somebody tries to ssh in as user &#8220;games&#8221; they&#8217;re toast.</li>
</ul>



<p>Indeed, there are any number of programs out there that aim to provide exactly these capabilities.<sup class="footnote"><a href="#fn1">1</a></sup>  What these techniques have in common is the need to measure the number of failed login attempts associated with a host and/or account over a period of time.  So how do the existing programs do it?  Sadly, a large number do it by scanning log files.  In other words, a scanner will look for a certain pattern (typically using regular expressions) in the logging output for your system and assume that it indicates a failed login attempt.  This is not a great idea.</p>

<p><span id="more-162"></span></p>

<p>What&#8217;s wrong with log file scanning, anyway?  The first (and least important, <span class="caps">IMHO</span>) mark against it is performance.  A typical system has dozens or hundreds of processes running at any time, each generating log output to some degree.  Well-written programs generate a trickle, but it&#8217;s not unusual for a program to accidentally ship (or be misconfigured) with debug-level logging enabled and thus generate a torrent of debug output.  By running a log file scanner you&#8217;ve now got a program that has to sift through <strong>every byte</strong> of that output looking for just one type of event!  This is certainly not the most efficient way to find out about login attempts.</p>

<p>Another bad aspect of log file scanning is that it relies on the specific formatting of log messages from specific programs.  If you replace OpenSSH with BogoSSH and BogoSSH uses a slightly different log output format then your scanner breaks.  Similarly, if the OpenSSH people ever decide to change their logging format (not that this is likely) then your scanner breaks.  If you install some new service that the scanner doesn&#8217;t know about it&#8217;s probably going to be totally unprotected unless it happens to format its log messages just like some other service the scanner understands.</p>

<p>But the worst thing about log file scanning is that sloppy implementations can actually open your system up to denial of service attacks!  I recently came across <a href="http://www.ossec.net/en/attacking-loganalysis.html">this article by Daniel B. Cid</a> that describes vulnerabilities in several popular log scanners that allow remote attackers to cause your machine to falsely blacklist any other machine of their choosing.  Even worse, one scanner allowed attackers to cut a machine off from the network entirely!  I refer you to the article for details, but the root causes of this problem are easy to describe:</p>


<ul>
<li>Regular expression matching is error-prone.  People aren&#8217;t terribly good at understanding the full class of strings that a given <span class="caps">R.E. </span>will match.  I&#8217;ve been doing complicated <span class="caps">R.E. </span>stuff for years now and I still have a terribly hard time writing bug-free regular expressions.</li>
<li>Log files are chock full of strings that come from insecure sources, like, say, random users on your machine and script kiddies all across the internet who want to crack your machine.  You do <strong>not</strong> want to be taking action automatically based on the contents of such an untrusted data source.  The article doesn&#8217;t even begin to mention what an attacker with local access could do by writing and executing a program that mimics sshd&#8217;s log output.  </li>
</ul>



<p>So how <strong>should</strong> this problem be solved?  By going straight to the horse&#8217;s mouth.  If you want to know about authentication attempts, talk to the authentication system.  Every modern *NIX system supports <span class="caps">PAM, </span><a href="http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/Linux-PAM_SAG.html">the Pluggable Authentication Module system</a>.  With a <span class="caps">PAM </span>module you can perform an action on any failed login attempt from <em>any</em> <span class="caps">PAM</span>-enabled service.  This allows you to create a concise, trustworthy authentication log file with a consistent format, which can then be monitored by a very simple (and thus secure) scanner.</p>

<p>One project that takes the <span class="caps">PAM </span>approach is <a href="http://sourceforge.net/projects/pam-abl">pam_abl</a> (auto-blacklist).  While it doesn&#8217;t use the specific strategy I described above (it builds a database rather than producing an authentication log file) it does get its info from the right source and is thus immune to these bogus log message attacks.  Unfortunately pam_abl is a bit inflexible and limited in its capabilities.  It doesn&#8217;t provide any way to blacklist a host if it tries to log in to a bogus account like &#8216;games&#8217;.  It doesn&#8217;t provide a way to throttle rather than blacklist.  And although it effectively ensures that an attacker will never have a chance to guess your account passwords it doesn&#8217;t provide a way of firewalling off a malicious host entirely.  Even worse, the maintainer of pam_abl doesn&#8217;t seem to have time to work on it any longer.  Hopefully somebody else will step up and turn this into <strong>the</strong> tool for stopping dictionary attacks dead in their tracks.</p>

<p class="footnote" id="fn1"><sup>1</sup> Here are a handful:</p>

<ul> <li> <a href="http://denyhosts.sourceforge.net/" title="sourceforge.net">denyhosts</a sourceforge.net></li> <li> <a href="http://www.fail2ban.org/wiki/index.php/Main_Page" title="fail2ban.org">fail2ban</a fail2ban.org></li> <li> <a href="http://www.aczoom.com/cms/blockhosts/" title="aczoom.com">blockhosts</a aczoom.com></li> <li> <a href="http://blocksshd.sourceforge.net/" title="sourceforge.net">blocsshd</a sourceforge.net></li> <li> <a href="http://www.zipcon.net/~sirius/crackblock.html" title="zipcon.net">crackblock</a zipcon.net></li> <li> <a href="http://shellter.sourceforge.net/" title="sourceforge.net">shellter</a sourceforge.net></li> <li> <a href="http://www.csc.liv.ac.uk/~greg/sshdfilter/" title="liv.ac.uk">sshdfilter</a liv.ac.uk></li> <li> <a href="http://anp.ath.cx/sshit/" title="anp.ath.cx">sshit</a anp.ath.cx></li>
<li> <a href="http://www.techfinesse.com/sshutout/sshutout.html" title="techfinesse.com">sshutout</a techfinesse.com></li> </ul>

<p><strong>Updated</strong>:  Removed ssh-faker from the footnote since it effectively alters the sshd service.</p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2008%2F01%2F28%2Fdictionary-attacks-or-why-log-file-monitoring-is-dumb%2F&amp;linkname=Dictionary%20attacks%2C%20or%20why%20log%20file%20monitoring%20is%20dumb"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2008/01/28/dictionary-attacks-or-why-log-file-monitoring-is-dumb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Announcing QLColorCode</title>
		<link>http://www.n8gray.org/blog/2007/12/03/announcing-qlcolorcode/</link>
		<comments>http://www.n8gray.org/blog/2007/12/03/announcing-qlcolorcode/#comments</comments>
		<pubDate>Tue, 04 Dec 2007 00:11:50 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[QLColorCode]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/blog/2007/12/03/announcing-qlcolorcode/</guid>
		<description><![CDATA[One of the features I&#8217;ve really liked in Leopard has been Quick Look.  It&#8217;s a really nice way to browse files quickly, without opening up a bunch of random apps.  However, the QL plugin that Apple provides for reading source code is, well, just plain boring.  You just get the text, in [...]]]></description>
			<content:encoded><![CDATA[<p>One of the features I&#8217;ve really liked in Leopard has been Quick Look.  It&#8217;s a really nice way to browse files quickly, without opening up a bunch of random apps.  However, the QL plugin that Apple provides for reading source code is, well, just plain boring.  You just get the text, in black &#038; white.  We all know how nice syntax highlighting is, so why didn&#8217;t they give us some of that?</p>

<p>Well, it turns out to be trivially easy to do a QL plugin that renders <span class="caps">HTML. </span> Mix in <a href="http://pygments.org/">Pygments</a>, the very capable syntax highlighting engine that can output <span class="caps">HTML, </span>and you&#8217;ve got a syntax highlighting QL plugin in under 100 lines of code!</p>

<p><img id="image153" src="http://www.n8gray.org/wp-content/uploads/2007/12/qlcolorcodeminisnapshot.png" alt="A Small Snapshot of QLColorCode" /></p>

<p>Rather than host this project myself I&#8217;ve decided to try making a Google Code project.  You can find it here:</p>

<p><a href="http://code.google.com/p/qlcolorcode/">http://code.google.com/p/qlcolorcode/</a></p>

<p>Enjoy!</p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2007%2F12%2F03%2Fannouncing-qlcolorcode%2F&amp;linkname=Announcing%20QLColorCode"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2007/12/03/announcing-qlcolorcode/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>MacFuse</title>
		<link>http://www.n8gray.org/blog/2007/02/16/macfuse/</link>
		<comments>http://www.n8gray.org/blog/2007/02/16/macfuse/#comments</comments>
		<pubDate>Fri, 16 Feb 2007 19:01:30 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/blog/2007/02/16/macfuse/</guid>
		<description><![CDATA[About a month ago, Google&#8217;s Amit Singh announced the availability of a port of the FUSE (Filesystems in USErspace) framework to Mac OS X.  Amit&#8217;s the guy who wrote the book on OS X internals, and probably understands OS X better than anyone else outside of Apple.  I&#8217;m not going to spend a [...]]]></description>
			<content:encoded><![CDATA[<p>About a month ago, Google&#8217;s Amit Singh <a href="http://googlemac.blogspot.com/2007/01/taming-mac-os-x-file-systems.html">announced</a> the availability of a port of the <a href="http://fuse.sourceforge.net/"><span class="caps">FUSE</span></a> (Filesystems in <span class="caps">USE</span>rspace) framework to Mac OS X.  Amit&#8217;s the guy who wrote <a href="http://osxbook.com/">the book on OS X internals</a>, and probably understands OS X better than anyone else outside of Apple.  I&#8217;m not going to spend a lot of time talking about why <span class="caps">FUSE </span>is a great idea &#8212; just check out the videos linked to from <a href="http://code.google.com/p/macfuse/">the MacFuse project page</a> and you&#8217;ll understand &#8212; but I do want to point out that <span class="caps">SSHFS </span>is really a pleasure to use.  It allows you to treat remote files just like local files <b>without any special server support</b>!  You do, of course, need <span class="caps">SSH </span>access to the machine in question, but this is usually the way I access remote machines anyhow.  </p>

<p>If you do need access to a machine where you don&#8217;t have an ssh account there&#8217;s also <span class="caps">FTPFS </span>and others.  There are <a href="http://fuse.sourceforge.net/wiki/index.php/FileSystems">a <strong>ton</strong> of <span class="caps">FUSE </span>filesystems</a> and it&#8217;s now become a pretty simple task to port them to OS X.  In the easiest cases it&#8217;s just a recompile.</p>

<p>Anyhow, big props to Amit Singh for doing a great service to the Mac community.  <a href="http://code.google.com/p/macfuse/">Get MacFuse here</a>.</p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2007%2F02%2F16%2Fmacfuse%2F&amp;linkname=MacFuse"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2007/02/16/macfuse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pronto to LIRC</title>
		<link>http://www.n8gray.org/blog/2007/01/28/pronto-to-lirc/</link>
		<comments>http://www.n8gray.org/blog/2007/01/28/pronto-to-lirc/#comments</comments>
		<pubDate>Sun, 28 Jan 2007 08:23:37 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/blog/2007/01/28/pronto-to-lirc/</guid>
		<description><![CDATA[In a recent post I discussed the URC-300 universal remote, one of my favorite new toys.  I yakked a bit about discrete codes and left off with a tantalizing tease about using discrete codes from the Remote Central database with LIRC.  Just to refresh your memory, this would be nifty because it would [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.n8gray.org/blog/2007/01/18/urc-300/">a recent post</a> I discussed the <span class="caps">URC</span>-300 universal remote, one of my favorite new toys.  I yakked a bit about discrete codes and left off with a tantalizing tease about using discrete codes from <a href="http://www.remotecentral.com/cgi-bin/files/rcfiles.cgi?area=pronto&amp;#038;db=discrete">the Remote Central database</a> with <a href="http://www.lirc.org/"><span class="caps">LIRC</span></a>.  Just to refresh your memory, this would be nifty because it would allow me to learn the discrete codes into the <span class="caps">URC</span>-300 (or any other learning remote), which otherwise wouldn&#8217;t be able to use them.</p>

<p><span id="more-137"></span></p>

<p>I&#8217;m not going to cover setting up <span class="caps">LIRC </span>or choosing an IR transceiver, since those topics are covered in detail on the <span class="caps">LIRC </span>website.  Let&#8217;s just say that there are many options available to you at pretty cheap prices, and if you&#8217;ve got any skill at all with a soldering iron you can build an IR transceiver for pocket change.</p>

<p>Discrete codes are almost always distributed in Philips Pronto format.  It&#8217;s sort of the <em>lingua franca</em> of remote controls.  What we <strong>really</strong> want is a nice little utility that reads a pronto code and spits out a <span class="caps">LIRC </span>config file.  There&#8217;s lots of info out there on the pronto format and IR codes in general, but, sadly, no such utility exists, so we have to do things the hard way.</p>

<p>First, an overview of our strategy.  When you push a button on a remote control it transmits a number to the device it controls.  There are a variety of techniques manufacturers use for encoding numbers as IR pulses, but in the end it&#8217;s all about getting <strong>one number</strong> (or &#8220;code&#8221;) to that device.  As you&#8217;ll see, it&#8217;s not too hard to get that code out of a pronto code, but it can be tricky to translate the encoding information to <span class="caps">LIRC. </span> What we&#8217;re going to do is let <span class="caps">LIRC </span>worry about all the encoding details by either using a pre-existing config file for the device or learning one from its remote.  Once we have that config it&#8217;s trivial to insert the new discrete codes.</p>

<p>To start with, we need a <span class="caps">LIRC </span>config file for the device in question.  I&#8217;m going to use the Roku Soundbridge as an example device here.  If you&#8217;re lucky there&#8217;s a ready-made config file on the <span class="caps">LIRC </span>website for your device.  If you&#8217;re <strong>really</strong> lucky it already has the discrete codes and you&#8217;re finished!  For the Soundbridge I&#8217;m not so lucky<sup class="footnote"><a href="#fn1">1</a></sup>.  Thankfully we have the original remote, so we can use <span class="caps">LIRC </span>to build a config file.  We fire up <code>irrecord</code> and follow the instructions (no need to actually record all the remote&#8217;s buttons), and pretty soon we have something like this:</p>



<pre>begin remote

  name  soundbridge
  bits           16
  [snip]
  pre_data_bits   16
  pre_data       0xF609
  [snip]
      begin codes
          power                    0x6897
          menu                     0xE817
          [snip]
      end codes
end remote</pre>



<p>There&#8217;s no need to understand everything in the file, so I&#8217;ve snipped out everything but the interesting parts.  What do we see here?  It looks like the Soundbridge remote sends 32-bit codes (a 16-bit header and a 16-bit code).  The code for toggling power is 0xF6096897 and the code for the menu button is 0xF609E817.  All the codes start with the same prefix (0xF609) so it&#8217;s only written once.</p>

<p>Now all we need is are the discrete power codes (we&#8217;ll call them power_on and power_off).  These are normally provided in one of two ways &#8212; as pronto codes or .ccf files.  We can use either one, but for now let&#8217;s assume you have a .ccf file.  In fact, <a href="http://www.rokulabs.com/">Roku Labs</a> provides a .ccf file for the Soundbridge on <a href="http://www.rokulabs.com/downloads/">their website</a>.  We&#8217;re going to use <a href="http://giantlaser.com/tonto/">Tonto</a>, the open-source ccf editor, to examine the contents of the .ccf file.  I&#8217;m not going to talk about installing Tonto, just suffice to say that it&#8217;s much the same as setting up any other Java program.</p>

<p>So now we do the following steps (<a href="http://www.n8gray.org/wp-content/uploads/2007/01/tontoarrows.png">here&#8217;s a screenshot</a> you can follow if you get lost):</p>


<ol>
<li>Start Tonto</li>
<li>Load Soundbridge.ccf</li>
<li>Use the tree view on the left side to navigate to devices/soundbridge/extras</li>
<li>Double-click &#8220;extras&#8221; to open a view of the extras panel.  The &#8220;power on&#8221; and &#8220;power off&#8221; buttons here are the discrete controls we&#8217;re looking for!</li>
<li>Double-click the &#8220;power on&#8221; button to examine its properties</li>
<li>Double-click the &#8220;[IR] Power On&#8221; line to see the details of the IR signal</li>
<li>Click the &#8220;Expert&#8221; button to see the &#8220;expert&#8221; details.  <img src='http://www.n8gray.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ol>



<p>Bingo!  In the expert details view there&#8217;s a HexValue field that reads f609c23d.  Remember how our other codes started with <span class="caps">F609</span>?  So all we need to do is add a line to the codes section of the <span class="caps">LIRC </span>config file:</p>



<pre>      begin codes
          power                    0x6897
          menu                     0xE817
          power_on                 0xC23D
      end codes
end remote</pre>



<p>Save this file in the appropriate place, point your IR transmitter at the Soundbridge (or whatever your device is), restart lircd, and try <code>irsend SEND_ONCE soundbridge power_on</code>.  The power should turn on.  Try it again and it should <strong>stay</strong> on.  Yay!  Now you can teach the code to your remote or use it with <span class="caps">LIRC. </span> Repeat with the rest of the codes you want to use and write macros that Just Work&#8482;.</p>

<p>One last detail.  If you <strong>don&#8217;t</strong> have a full ccf file and just have the pronto code (a <em>very</em> long string of hex digits) for a command, you can still extract the code.  In the first (non-expert) IR Signal dialog we saw in Tonto, the text field contains the pronto code for the button.  If you paste in a different pronto code and then click &#8220;expert&#8221; you&#8217;ll see the hex code for that code.  So just use any old ccf file you can find, any device, any button, and paste in the code you need.  This is how I got the discrete power codes for my <span class="caps">JVC TV.</span></p>

<p>[1] If <strong>you</strong> have a Soundbridge your luck should be much better now.  I&#8217;ve sent in the Soundbridge config file to the <span class="caps">LIRC </span>developers so it should be in their database soon.  <img src='http://www.n8gray.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2007%2F01%2F28%2Fpronto-to-lirc%2F&amp;linkname=Pronto%20to%20LIRC"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2007/01/28/pronto-to-lirc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rootkit Brought to You by Sony</title>
		<link>http://www.n8gray.org/blog/2005/11/01/rootkit-brought-to-you-by-sony/</link>
		<comments>http://www.n8gray.org/blog/2005/11/01/rootkit-brought-to-you-by-sony/#comments</comments>
		<pubDate>Wed, 02 Nov 2005 06:41:00 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hacking]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/sandbox/wordpress/?p=50</guid>
		<description><![CDATA[
For anybody who thinks that fair-use rights activists like the EFF are being too paranoid about DRM and &#8220;Trusted&#8221; Computing (AKA Treacherous Computing), read this.  Sony&apos;s &#8220;copy protected&#8221; CDs install a CD driver, IDE driver, and a rootkit to cover their tracks.  This rootkit can be found by some spyware detection programs, but [...]]]></description>
			<content:encoded><![CDATA[<p>
For anybody who thinks that fair-use rights activists like <a href="http://www.eff.org/">the <span class="caps">EFF</span></a> are being too paranoid about <span class="caps">DRM </span>and <a href="http://www.gnu.org/philosophy/can-you-trust.html">&#8220;Trusted&#8221; Computing</a> (AKA Treacherous Computing), <a href="http://www.sysinternals.com/blog/2005/10/sony-rootkits-and-digital-rights.html">read this</a>.  Sony&apos;s &#8220;copy protected&#8221; CDs install a CD driver, <span class="caps">IDE </span>driver, and a <em>rootkit</em> to cover their tracks.  This rootkit can be found by some spyware detection programs, but if a user deletes it <em><a href="http://www.theregister.co.uk/2005/11/01/sony_rootkit_drm/">their system will become unbootable!</a></em>  <br />
<p>
It took an expert like Mark, who&apos;s the coauthor of <i>Windows Internals</i>, quite a while to get to the bottom of this.  Now imagine this was happening on a &#8220;Trusted&#8221; platform where even power-users like Mark would be power<em>less</em> to undo the damage, and maybe you can see just how bad the situation can get.  Media corporations have shown time and time again that they are not just disrespectful of customer rights but downright <em>contemptuous</em> of them.  Any scheme like Treacherous Computing that involves trusting them to do the right thing is practically a guarantee of abuse.<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2005%2F11%2F01%2Frootkit-brought-to-you-by-sony%2F&amp;linkname=Rootkit%20Brought%20to%20You%20by%20Sony"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2005/11/01/rootkit-brought-to-you-by-sony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hardware Links</title>
		<link>http://www.n8gray.org/blog/2005/10/24/hardware-links/</link>
		<comments>http://www.n8gray.org/blog/2005/10/24/hardware-links/#comments</comments>
		<pubDate>Tue, 25 Oct 2005 05:42:00 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/sandbox/wordpress/?p=51</guid>
		<description><![CDATA[
Ever wanted to know the pinout of a PlayStation controller connector?  How about how to build a null-modem cable?  Who among us hasn&apos;t, at some point, wanted to build their own PS/2 to Serial Mouse adapter?  Thanks to the folks at the Hardware Book, you can get all this information and more!

Once [...]]]></description>
			<content:encoded><![CDATA[<p>
Ever wanted to know the pinout of a PlayStation controller connector?  How about how to build a null-modem cable?  Who among us <i>hasn&apos;t</i>, at some point, wanted to build their own PS/2 to Serial Mouse adapter?  Thanks to the folks at <a href="http://www.hardwarebook.net">the Hardware Book</a>, you can get all this information and more!<br />
<p>
Once you&apos;ve figured out the pinout of that Amiga Video connector and want to build a custom circuit, it&apos;s good to know how to <a href="http://www.5bears.com/pcb.htm">make your own iron-on <span class="caps">PCB </span>masks</a> using a laser printer and photo paper.  <a href="http://www.fullnet.com/u/tomg/gooteepc.htm">Here&apos;s another site</a> with lots of info.<br />
<p>
Of course, you&apos;ll actually need to know a little bit about electronics to use this knowledge.  <a href="http://www.iguanalabs.com/advanced.htm">These guys</a> have some tutorials, and <a href="http://www.makezine.com/blog/">these guys</a> have cool ideas.<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2005%2F10%2F24%2Fhardware-links%2F&amp;linkname=Hardware%20Links"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2005/10/24/hardware-links/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Aux-In Hack for 2005/06 Subaru Legacy/Outback with 6-CD changer</title>
		<link>http://www.n8gray.org/blog/2005/10/11/aux-in-hack-for-200506-subaru-legacyoutback-with-6-cd-changer/</link>
		<comments>http://www.n8gray.org/blog/2005/10/11/aux-in-hack-for-200506-subaru-legacyoutback-with-6-cd-changer/#comments</comments>
		<pubDate>Tue, 11 Oct 2005 14:42:00 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[Car]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/sandbox/wordpress/?p=54</guid>
		<description><![CDATA[
About a year ago I bought a 2005 Subaru Legacy wagon with an in-dash 6-CD changer.  It&apos;s proven to be an excellent car, but it has one nagging flaw: there&apos;s no way to connect an iPod to the stereo.  The usual way this is done for factory stereos without aux-in jacks is to [...]]]></description>
			<content:encoded><![CDATA[<p>
About a year ago I bought a 2005 Subaru Legacy wagon with an in-dash 6-CD changer.  It&apos;s proven to be an excellent car, but it has one nagging flaw: there&apos;s no way to connect an iPod to the stereo.  The usual way this is done for factory stereos without aux-in jacks is to use a kit to convert the CD changer input to an aux-in, but with the changer integrated into the stereo  that&apos;s not an option.  Another option would be to replace the whole stereo with a 3&apos;rd party unit, but the Subie&apos;s stereo is <b>integrated with the heating and AC controls</b><img src="The" alt="" /><br />
<p>
When all else fails, there&apos;s the option of using an FM modulator connected directly to the antenna input for the stereo.  Amazingly enough, Subaru made even this option painful by using a non-standard antenna cable!  <a href="http://www.metraonline.com/">Metra</a> now sells the cable you need to make this work, but the sound quality for FM modulators is only marginally acceptable.  Oh, and don&apos;t even <b>mention</b> those FM transmitters you find at Target&#8211;those just sound awful!<br />
<p>
However, thanks to a couple of enterprising hardware hackers at <a href="http://legacygt.com/">legacygt.com</a> my problem has been solved.  A fine gentleman known as centerpunch <a href="http://legacygt.com/forums/showthread.php?t=2936">made the whole thing possible</a>, and another called jazzymt <a href="http://legacygt.com/forums/showthread.php?t=18504">made it easy</a>.  The install requires you to dismantle the stereo and connect a circuit with an aux-in between the CD changer and the main stereo circuit board.  I did the install myself this afternoon and thought I&apos;d share some tips for anybody who wants to try it themselves.  But first, the standard disclaimer.  These tips are based on my experience with my car.  I&apos;m not an expert, and I don&apos;t know your car.  Maybe they&apos;ll work for you, maybe they won&apos;t, but don&apos;t blame me if you break something trying to follow what I&apos;ve written here.<br />
<p>
There are three pieces of trim that will make your life difficult.<br />
<ul>
    <li><b>The emergency-brake cover.</b>  This is the first thing you&apos;re asked to remove, and unfortunately it can be really tough to get out.  It&apos;s hard to get a hold of because the driver&apos;s seat obstructs it.  (It helps to lower the driver&apos;s seat completely if you have power seats.)  The cover is held on by two clips, one at the front and one at the rear.  If you&apos;re clever maybe you can figure out how to unclip them.  If you&apos;re like me, on the other hand, you just have to grab the edge and pull straight up, really hard.
    <br />
    <li><b>The Silver ring around the shifter.</b>  (I have the automatic transmission, and this might not be a problem if you have the manual.)  Prying that thing out was quite frightening.  There it is, right in the middle of the cabin, all shiny, just waiting to be scratched, bent, or otherwise befouled.  The trim underneath it gives a little too easily as you try to pry the ring up.  It&apos;s scary stuff.  To defeat it, here&apos;s what you need to know:
    <ul>
        <li> To pry up the ring, use a well-padded flat head screwdriver, and twist.  To pad mine, I used the felt pad from the armrest cubby underneath the screwdriver and two playing cards on top of it.
        <li> The clips holding the ring in are on the sides, at the top and bottom.  The one on the lower right is not quite at the bottom, but about an inch from the bottom.  Dont pry anywhere else or you might bend the ring!  Be as gentle as possible, and work each clip a little bit at a time.
    </ul>
    <br />
    <li><b>The arm rest console.</b>  This damned thing was the bane of my existence the first time I removed the stereo.  There are two bolts inside the console that are easy enough to remove, but the two clips up near the shifter would not let go without a serious struggle!  I was <b>very</b> concerned that I was going to break the console if I pulled with the amount of force required to detach those clips.  I thought about drilling out the clip that&apos;s visible, but that wouldn&apos;t have helped with the hidden right-hand one.  In the end, once again, brute force did the trick and nothing broke.  Just pull straight up, really hard, and don&apos;t blame me if it breaks for you.
</ul>

<p>
<a href="http://www.n8gray.org/photos/car-stereo">Here are some pictures</a> that I took the first time I took apart the stereo, back in January.  I&apos;ve always found it helps to know the locations of the clips holding the trim in when I&apos;m trying to take something out.<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2005%2F10%2F11%2Faux-in-hack-for-200506-subaru-legacyoutback-with-6-cd-changer%2F&amp;linkname=Aux-In%20Hack%20for%202005%2F06%20Subaru%20Legacy%2FOutback%20with%206-CD%20changer"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2005/10/11/aux-in-hack-for-200506-subaru-legacyoutback-with-6-cd-changer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>GCC Preprocessor Defines</title>
		<link>http://www.n8gray.org/blog/2004/07/27/gcc-preprocessor-defines/</link>
		<comments>http://www.n8gray.org/blog/2004/07/27/gcc-preprocessor-defines/#comments</comments>
		<pubDate>Tue, 27 Jul 2004 07:14:00 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/sandbox/wordpress/?p=74</guid>
		<description><![CDATA[Here&apos;s a useful tidbit that I thought I would share.  If you want to find out
all of the built-in #define&apos;s that GCC gives you, try this:

touch dummy_file.c; gcc -E -dM dummy_file.c

On recent versions of GCC this will give you a list of all the predefined
macros.  On older systems (I don&apos;t know how far [...]]]></description>
			<content:encoded><![CDATA[<p>Here&apos;s a useful tidbit that I thought I would share.  If you want to find out
all of the built-in #define&apos;s that <span class="caps">GCC </span>gives you, try this:<br />
</p>
<code>touch dummy_file.c; gcc -E -dM dummy_file.c</code>

<p>On recent versions of <span class="caps">GCC </span>this will give you a list of all the predefined
macros.  On older systems (I don&apos;t know how far back) you can try this:<br />
</p>
<code>gcc -dumpspecs</code>

<p>It&apos;s harder to read, but many of the platform-specific macros are in there.<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2004%2F07%2F27%2Fgcc-preprocessor-defines%2F&amp;linkname=GCC%20Preprocessor%20Defines"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2004/07/27/gcc-preprocessor-defines/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tag Generators for OCaml</title>
		<link>http://www.n8gray.org/blog/2004/07/23/tag-generators-for-ocaml/</link>
		<comments>http://www.n8gray.org/blog/2004/07/23/tag-generators-for-ocaml/#comments</comments>
		<pubDate>Fri, 23 Jul 2004 07:37:00 +0000</pubDate>
		<dc:creator>n8</dc:creator>
				<category><![CDATA[OCaml]]></category>

		<guid isPermaLink="false">http://www.n8gray.org/sandbox/wordpress/?p=75</guid>
		<description><![CDATA[
Throughout my programming career, I&apos;ve found tags to be incredibly useful, so
when I started working in OCaml one of the
first things I sought out was a tag generator.  (For those of you who don&apos;t
know, tags are essentially cross-references that allow you to find the
definition of any identifier in a program.)  There are a [...]]]></description>
			<content:encoded><![CDATA[<p>
Throughout my programming career, I&apos;ve found tags to be incredibly useful, so<br />
when I started working in <a href="http://caml.inria.fr">OCaml</a> one of the<br />
first things I sought out was a tag generator.  (For those of you who don&apos;t<br />
know, tags are essentially cross-references that allow you to find the<br />
definition of any identifier in a program.)  There are a handful of OCaml tag<br />
generators out there, including:<br />
<ul>
    <br />
    <li>ocamltags:  This is included with OCaml and appears to be Emacs-based. 
    I&apos;ve never figured out how to make it work.<br />
    <br />
    <li><a href="http://perso.rd.francetelecom.fr/alvarado/">otags</a>:
    Written by Cuihtlauac Alvarado and Jean-Francois Monin.  This is based on a<br />
    camlp4 parser, which suggests that it should be quite accurate.  It also<br />
    seems that you can use additional parsers with the -pa option.  I&apos;ve had a<br />
    lot of success with this tagger, but as of this<br />
    writing it hasn&apos;t been updated for OCaml 3.08. <a href="http://membres.lycos.fr/moninjf/Ocaml/">(older versions)</a> <a href="http://www-verimag.imag.fr/PEOPLE/monin/Soft/Otags/">(alternate<br />
    link)</a><br />
    <br />
    <li><a href="http://mallorn.ucdavis.edu/~ijtrotts/">taglet</a>: Written by
    Issac Trotts. It&apos;s regex-based, so it won&apos;t work with custom camlp4<br />
    preprocessor macros.  The idea behind taglet is to<br />
    only make tags for modules.  The author belives that this ends up being<br />
    easier to deal with than having tags for every identifier.  <br />
    I&apos;m not so sure myself.

</ul>

<p> Leave a comment if you know of any other tag generators for OCaml!<a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Fwww.n8gray.org%2Fblog%2F2004%2F07%2F23%2Ftag-generators-for-ocaml%2F&amp;linkname=Tag%20Generators%20for%20OCaml"><img src="http://www.n8gray.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.n8gray.org/blog/2004/07/23/tag-generators-for-ocaml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
