<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.sharpcube.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Rodrigo Sieiro</title>
	
	<link>http://rodrigo.sharpcube.com</link>
	<description>Rodrigo Sieiro's Personal Blog</description>
	<lastBuildDate>Thu, 30 Jun 2011 13:52:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.sharpcube.com/rodrigo_sharpcube" /><feedburner:info uri="rodrigo_sharpcube" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>New Layout</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/_KVQlIL-7Z0/</link>
		<comments>http://rodrigo.sharpcube.com/2011/05/08/new-layout/#comments</comments>
		<pubDate>Sun, 08 May 2011 03:22:13 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Meta]]></category>
		<category><![CDATA[Template]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=207</guid>
		<description><![CDATA[So much for that &#8220;one post per week&#8221; resolution, huh? Just a quick post to announce that this blog is now using a new template. Clean, simple and elegant, it&#8217;s based on Cleanr but with several modifications I made. The previous template was too visually polluted and full of bugs, I&#8217;ve been thinking about changing [...]]]></description>
			<content:encoded><![CDATA[<p>So much for that &#8220;one post per week&#8221; resolution, huh?</p>
<p>Just a quick post to announce that this blog is now using a new template. Clean, simple and elegant, it&#8217;s based on <a href="http://wordpress.org/extend/themes/cleanr">Cleanr</a> but with several modifications I made. The previous template was too visually polluted and full of bugs, I&#8217;ve been thinking about changing it for quite a while. If you read the blog through its RSS feed, be sure to come visit and check out the new layout!</p>
<p>I also updated <a href="http://rodrigo.sharpcube.com/2010/06/20/using-and-sharing-a-vpn-connection-on-your-mac/">my post about VPN sharing on a Mac</a>. A lot of common problems and great solutions were getting lost in the middle of the comments, so I grouped them in a <em>Troubleshooting</em> section.</p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/_KVQlIL-7Z0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2011/05/08/new-layout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2011/05/08/new-layout/</feedburner:origLink></item>
		<item>
		<title>My First Open Source Project</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/0F1bx12zAQQ/</link>
		<comments>http://rodrigo.sharpcube.com/2011/01/19/my-first-open-source-project/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 02:27:46 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Project]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=169</guid>
		<description><![CDATA[As I wrote in the previous post, one of my New Year&#8217;s resolution for 2011 is to write at least one blog post per week. Unfortunately, it&#8217;s not something I can simply mark as &#8220;done&#8221; until the end of the year. But another item on that list was to publish my first open source project, [...]]]></description>
			<content:encoded><![CDATA[<p>As I wrote in the previous post, one of my New Year&#8217;s resolution for 2011 is to write at least one blog post per week. Unfortunately, it&#8217;s not something I can simply mark as &#8220;done&#8221; until the end of the year. But another item on that list was to publish my first open source project, and that&#8217;s what I decided to do today. One of the projects I&#8217;m working on (a WordPress site) needed a sidebar widget that looked like a calendar, with each cell being a month showing how many posts were published on that month. Since I couldn&#8217;t find a plugin with that functionality, I decided to write my own. After I finished writing the plugin for the project, I realized that it was fairly simple to make it more generic and publish as a WP plugin.</p>
<p><span id="more-169"></span></p>
<p>Writing a WordPress plugin is quite simple. There are a few things you need to do to make it a sidebar widget (basically you just have to extend the <code>WP_Widget</code> class and implement a few functions) but nothing too complicated. I also took the opportunity to learn how to use AJAX inside a WP plugin, since I didn&#8217;t want to refresh the whole page when changing years in the calendar.</p>
<p>So there you go: <strong>today I&#8217;m publishing my first open source project</strong>, a WordPress plugin called <strong>Month Calendar</strong>. The source is available at <a href="https://github.com/rsieiro/month-calendar">GitHub</a>, and the plugin is also published on <a href="http://wordpress.org/extend/plugins/month-calendar/">WordPress Plugin Directory</a>. It&#8217;s an important milestone to me, and it was a fun pet project. I learned a few things while making it, and now I feel ready to write a couple more complex plugins I&#8217;ve been planning. You can see the plugin working on the sidebar of this blog, if you&#8217;re curious.</p>
<p>Fun fact: the hardest part in the development process was to publish the plugin to the WordPress Directory, since I use Git and WP forces you to use a SVN repository. But after playing with Git&#8217;s SVN bridge for a while, I found an elegant solution. Since it&#8217;s not trivial as I thought it would be, I&#8217;ll write a blog post tomorrow detailing the whole process.</p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/0F1bx12zAQQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2011/01/19/my-first-open-source-project/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2011/01/19/my-first-open-source-project/</feedburner:origLink></item>
		<item>
		<title>Narrowing My Audience</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/3gTge2RxUVE/</link>
		<comments>http://rodrigo.sharpcube.com/2011/01/12/narrowing-my-audience/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 19:48:15 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Meta]]></category>
		<category><![CDATA[Language]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=164</guid>
		<description><![CDATA[When I started this blog, I wasn&#8217;t sure if I was supposed to write in English or Portuguese. Sure, I live in Brazil and my mother tongue is Portuguese, but most sites and blogs I read are in English &#8211; it&#8217;s effectively the main language in software development. After thinking about it for a while, [...]]]></description>
			<content:encoded><![CDATA[<p>When I started this blog, I wasn&#8217;t sure if I was supposed to write in English or Portuguese. Sure, I live in Brazil and my mother tongue is Portuguese, but most sites and blogs I read are in English &#8211; it&#8217;s effectively the main language in software development. After thinking about it for a while, I decided to create two identical blogs, one in English and one in Portuguese. That way I could reach a wider audience by writing in English, but also have something for my fellow brazilians.</p>
<p><span id="more-164"></span></p>
<p>First, let me explain how my writing &#8220;routine&#8221; was planned: I would think about a topic and write a blog post in English first. Since I&#8217;m not perfectly fluent in English, it&#8217;s easier for me to translate something from English to Portuguese than the opposite. After the post was done, I&#8217;d then translate it to Portuguese and post both versions at the same time.</p>
<p>It seemed like a good plan, but it never worked. While writing, I kept thinking about how my text would look like after the translation, which made me go back and rewrite phrases all the time so they could look &#8220;right&#8221; in both languages. And even after all that effort, when I read my own translated posts in Portuguese, they felt wrong. I don&#8217;t know how to explain, but the thought process is different in each language, so a translation is never as good as a text originally written in Portuguese. Eventually, I simply lost interest in writing: just thinking about all the burden I had to go through for a simple blog post was enough for me to give up.</p>
<p>Now that we&#8217;re starting 2011 (New Year&#8217;s resolutions, you know the drill) I thought that trying to keep a schedule of one post per week could be a great challenge for me. But to achieve that, I&#8217;d have to change my methods somehow. So I decided to take a look at my blog statistics, and I noticed that 95% of all my traffic was going to the english version. I know that it has been several months since my last post, but while the Portuguese version had days with no traffic at all, the English version kept a steady number of visits every day (mostly thanks to google and <a href="http://rodrigo.sharpcube.com/2010/06/20/using-and-sharing-a-vpn-connection-on-your-mac/">my post about VPN sharing</a>).</p>
<p>Long story short: the Portuguese version is gone. By trying to satisfy everyone, I ended up with a blog with no posts and a Portuguese version that never felt right (hence no visits). Not to mention that by keeping the Portuguese version I was going against my own belief: that if you&#8217;re a software developer, you should learn English, whether you like the language or not. I advocate that to all my developer friends here in Brazil, and yet I was providing a translation of my own posts to non-english speakers (I know it&#8217;s a controversial subject, but I&#8217;ll leave that for another post). So now this blog is English only, and hopefully it&#8217;ll actually be a blog again (with new posts, you know).</p>
<p>Sorry about the rant. Simply removing the Portuguese version without any explanation didn&#8217;t feel right.</p>
<p><em>(There&#8217;s a great analogy in this post about compromise and software development, but I&#8217;ll leave that as an exercise to you)</em></p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/3gTge2RxUVE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2011/01/12/narrowing-my-audience/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2011/01/12/narrowing-my-audience/</feedburner:origLink></item>
		<item>
		<title>Using OAuth with Twitter in Cocoa/Objective-C</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/UF7EicEcVkg/</link>
		<comments>http://rodrigo.sharpcube.com/2010/06/29/using-oauth-with-twitter-in-cocoa-objective-c/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 18:47:36 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[OAuth]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=134</guid>
		<description><![CDATA[Lately OAuth is getting pretty popular. Several websites are adopting it as the preferred authentication mechanism for their APIs, and most of them as the only one. So what exactly is OAuth, and what does it do? According to the official website: This is what OAuth does, it allows the you the User to grant [...]]]></description>
			<content:encoded><![CDATA[<p>Lately <em>OAuth</em> is getting pretty popular. Several websites are adopting it as the preferred authentication mechanism for their APIs, and most of them as the only one. So what exactly is <em>OAuth</em>, and what does it do? According to the <a href="http://oauth.net/">official website</a>:</p>
<blockquote><p>This is what OAuth does, it allows the you the User to grant access to your private resources on one site (which is called the Service Provider), to another site (called Consumer, not to be confused with you, the User). While OpenID is all about using a single identity to sign into many sites, OAuth is about giving access to your stuff without sharing your identity at all (or its secret parts).</p></blockquote>
<p>Basically, <em>OAuth</em> is a way to authenticate to a webservice without having to store the user&#8217;s password, and in most cases without even having to ask the user for it. Twitter adopted <em>OAuth</em> for its API, and as of <a href="http://www.countdowntooauth.com/">August 16th</a>, it&#8217;ll be the only way to use the API. In this post I will explain how to use <em>OAuth</em> to authenticate with Twitter in Cocoa/Objective-C.</p>
<p><span id="more-134"></span></p>
<h3>Choosing the authentication method</h3>
<p>Twitter offers us three ways to authenticate using <em>OAuth</em>. The first, mostly for web applications, is to send a callback URL with your request, so after the user authorizes your application he gets redirected to the callback URL, and your app can proceed from that. The second, directed to desktop and mobile applications, is to use out-of-band authentication: after authorization, Twitter provides the user with a PIN code that he can type in your app to proceed. And the third one is to send the user&#8217;s login and password via <em>xAuth</em>. Although it may seem easier to use the last option, Twitter considers it the least desired way (as the user still has to type his password in your app), and to use it you need to directly ask Twitter for permission, sending details about your app and why you want to use it to <a href="mailto:api@twitter.com">api@twitter.com</a>. In this guide we&#8217;ll use out-of-band/PIN code authentication, since this method doesn&#8217;t require you to set up a callback URL or ask Twitter for permission.</p>
<h3>Getting started</h3>
<p>First things first: if you haven&#8217;t done yet, go to <a href="http://twitter.com/apps">Twitter Application Platform</a> and register your app to use <em>OAuth</em> (yes, you can register a test application, no need for approval). After registering, write down the <em>Consumer key</em> and the <em>Consumer secret</em> for your app, as you&#8217;ll need them in a moment.</p>
<p>In this sample project, I&#8217;m using <a href="http://github.com/jdg/oauthconsumer">OAuthConsumer</a> to handle <em>OAuth</em> requests. There are two versions available, this one I linked to was modified to handle Twitter&#8217;s PIN code. Be warned that there&#8217;s a bug on its code: in line <code>214</code> of <code>OAMutableURLRequest.m</code>, it should read:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>token.verifier <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>token.verifier isEqualToString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span></pre></div></div>

<p>I will eventually submit this fix to the author, but right now you can just change it yourself or use the version bundled with my code sample that you can download at the end of this post. It took me <strong>hours</strong> to figure that out.</p>
<p><strong>Update:</strong> thanks to <a href="http://raphaelcaixeta.com/">Raphael Caixeta</a>, I noticed I linked to the wrong version of <strong>OAuthConsumer</strong> (there are several different forks). He kindly created a ZIP file with the correct version, and you can download it <a href="http://rodrigo.sharpcube.com/wp-content/uploads/2010/06/OAuth.zip">here</a>.</p>
<p>Twitter&#8217;s <em>OAuth</em> authentication (using a PIN code) is a three step process. First you ask for a <em>Request Token</em>, then you redirect the user to a webpage so he can authorize your app and get the PIN code, and finally you ask for an <em>Access Token</em>. After that you just have to use that <em>Access Token</em> to sign every request you make.</p>
<h3>Request Token</h3>
<p>Less talk, more code. Here we go:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">OAConsumer <span style="color: #002200;">*</span>consumer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAConsumer alloc<span style="color: #002200;">&#93;</span> initWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CONSUMER_KEY&quot;</span>
                                                secret<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CONSUMER_SECRET&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
OADataFetcher <span style="color: #002200;">*</span>fetcher <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OADataFetcher alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>url <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;https://api.twitter.com/oauth/request_token&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
OAMutableURLRequest <span style="color: #002200;">*</span>request <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAMutableURLRequest alloc<span style="color: #002200;">&#93;</span> initWithURL<span style="color: #002200;">:</span>url
                                                               consumer<span style="color: #002200;">:</span>consumer
                                                                  token<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                                                                  realm<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                                                      signatureProvider<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>request setHTTPMethod<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;POST&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>fetcher fetchDataWithRequest<span style="color: #002200;">:</span>request 
                     delegate<span style="color: #002200;">:</span>self
            didFinishSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>requestTokenTicket<span style="color: #002200;">:</span>didFinishWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
              didFailSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>requestTokenTicket<span style="color: #002200;">:</span>didFailWithError<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>First, we create an <code>OAConsumer</code> object, using the consumer key and secret Twitter gave us (don&#8217;t forget to replace <em>CONSUMER_KEY</em> and <em>CONSUMER_SECRET</em> with the ones you got earlier). Then we create an <code>OAMutableURLRequest</code> using this consumer and Twitter&#8217;s <em>Request Token</em> URL. We set the request to use <code>HTTP POST</code> and finally use an <code>OADataFetcher</code> to submit it. This call uses two delegate methods for success and fail. Here&#8217;s the code for the success method:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> requestTokenTicket<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>OAServiceTicket <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>ticket didFinishWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>data
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>ticket.didSucceed<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>responseBody <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>data 
                                                       encoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
&nbsp;
        accessToken <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAToken alloc<span style="color: #002200;">&#93;</span> initWithHTTPResponseBody<span style="color: #002200;">:</span>responseBody<span style="color: #002200;">&#93;</span>;
&nbsp;
        <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>address <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span>
                             <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;https://api.twitter.com/oauth/authorize?oauth_token=%@&quot;</span>,
                             accessToken.key<span style="color: #002200;">&#93;</span>;
&nbsp;
        <span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>url <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span>address<span style="color: #002200;">&#93;</span>;
        <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSWorkspace</span> sharedWorkspace<span style="color: #002200;">&#93;</span> openURL<span style="color: #002200;">:</span>url<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>We get the response body and use the <code>initWithHTTPResponseBody</code> method from <code>OAToken</code> to create our <em>Request Token</em>. Then we use the token key and redirect the user to a Twitter page where he can authorize our app and get the PIN code. This is what the user will see:</p>
<p><a href="http://rodrigo.sharpcube.com/wp-content/uploads/2010/06/authorization.png"><img src="http://rodrigo.sharpcube.com/wp-content/uploads/2010/06/authorization.png" alt="Twitter Authorization" title="Twitter Authorization" width="500" class="aligncenter" /></a></p>
<p>After authorizing, Twitter will give the user a PIN code (7 digits) that he should write or copy. We&#8217;ll use this PIN code in the next step.</p>
<h3>Access Token</h3>
<p>To get the <em>Access Token</em> the code is pretty similar:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">OAConsumer <span style="color: #002200;">*</span>consumer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAConsumer alloc<span style="color: #002200;">&#93;</span> initWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CONSUMER_KEY&quot;</span>
                                                secret<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CONSUMER_SECRET&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
OADataFetcher <span style="color: #002200;">*</span>fetcher <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OADataFetcher alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>url <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;https://api.twitter.com/oauth/access_token&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>accessToken setVerifier<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;PIN_CODE&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
OAMutableURLRequest <span style="color: #002200;">*</span>request <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAMutableURLRequest alloc<span style="color: #002200;">&#93;</span> initWithURL<span style="color: #002200;">:</span>url
                                                               consumer<span style="color: #002200;">:</span>consumer
                                                                  token<span style="color: #002200;">:</span>accessToken
                                                                  realm<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                                                      signatureProvider<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>request setHTTPMethod<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;POST&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>fetcher fetchDataWithRequest<span style="color: #002200;">:</span>request 
                     delegate<span style="color: #002200;">:</span>self
            didFinishSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>accessTokenTicket<span style="color: #002200;">:</span>didFinishWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
              didFailSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>accessTokenTicket<span style="color: #002200;">:</span>didFailWithError<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Now we use the PIN code as the <code>verifier</code> in our token. Then, in our request, we send the token we got earlier (now including the PIN code). Everything else is pretty much the same. Here&#8217;s the new success delegate method:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span> accessTokenTicket<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>OAServiceTicket <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>ticket didFinishWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>data
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>ticket.didSucceed<span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>responseBody <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>data 
                                                       encoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
&nbsp;
        accessToken <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAToken alloc<span style="color: #002200;">&#93;</span> initWithHTTPResponseBody<span style="color: #002200;">:</span>responseBody<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Easy, right? We just get the response body and recreate our token using the new data. This new token is everything we need to sign our requests from now on. As long as you keep this token, you should never have to authorize your app again. The <code>OAToken</code> class even provides you with methods to store and retrieve this token, so you can keep it after closing your app and starting again.</p>
<p>Now you can go ahead and use any Twitter API method you want. Here&#8217;s an example to request the user&#8217;s home timeline:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">OAConsumer <span style="color: #002200;">*</span>consumer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAConsumer alloc<span style="color: #002200;">&#93;</span> initWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CONSUMER_KEY&quot;</span>
                                                secret<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CONSUMER_SECRET&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
OADataFetcher <span style="color: #002200;">*</span>fetcher <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OADataFetcher alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>url <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSURL</span> URLWithString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;http://api.twitter.com/1/statuses/home_timeline.xml&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
OAMutableURLRequest <span style="color: #002200;">*</span>request <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>OAMutableURLRequest alloc<span style="color: #002200;">&#93;</span> initWithURL<span style="color: #002200;">:</span>url
                                                               consumer<span style="color: #002200;">:</span>consumer
                                                                  token<span style="color: #002200;">:</span>accessToken
                                                                  realm<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span>
                                                      signatureProvider<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>fetcher fetchDataWithRequest<span style="color: #002200;">:</span>request 
                     delegate<span style="color: #002200;">:</span>self
            didFinishSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>apiTicket<span style="color: #002200;">:</span>didFinishWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
              didFailSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>apiTicket<span style="color: #002200;">:</span>didFailWithError<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<h3>Sample Project</h3>
<p>As you probably noticed, this post contains only code directly related to what I&#8217;m trying to explain. If you want the whole thing (including my modified <code>OAuthConsumer</code>) I&#8217;ve created a sample project including all the methods I used here and a very basic interface with some buttons you can use to call each method (and fields for consumer key, consumer secret and the PIN code).</p>
<div class="yellow-box">Download the sample project for this post: <a href="http://rodrigo.sharpcube.com/wp-content/uploads/2010/06/OAuthDemo.zip">OAuthDemo.zip</a> (57 KB)</div>
<p>The sample project requires Mac OS X 10.5 (Leopard).</p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/UF7EicEcVkg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2010/06/29/using-oauth-with-twitter-in-cocoa-objective-c/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2010/06/29/using-oauth-with-twitter-in-cocoa-objective-c/</feedburner:origLink></item>
		<item>
		<title>Using (and sharing) a VPN connection on your Mac</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/wpRjPMzRZVE/</link>
		<comments>http://rodrigo.sharpcube.com/2010/06/20/using-and-sharing-a-vpn-connection-on-your-mac/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 02:11:27 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Hacking]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[OpenVPN]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Share]]></category>
		<category><![CDATA[VPN]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=127</guid>
		<description><![CDATA[Update (2011-05-07): I added a Troubleshooting section at the end of this article, grouping together several common problems (and solutions) people posted in the comments. First of all, sorry for the lack of posts, I&#8217;ve been kinda busy lately. I finally updated my development machine to Snow Leopard (I was on Leopard 10.5.7) and I [...]]]></description>
			<content:encoded><![CDATA[<div class="yellow-box"><strong>Update (2011-05-07)</strong>: I added a <em>Troubleshooting</em> section at the end of this article, grouping together several common problems (and solutions) people posted in the comments.</div>
<p>First of all, sorry for the lack of posts, I&#8217;ve been kinda busy lately. I finally updated my development machine to Snow Leopard (I was on Leopard 10.5.7) and I took the opportunity to sort and organize all my backups, documents and stuff. I&#8217;m still not really done with my backup procedures, but at least I&#8217;m covered in case of a crash (after the <a href="http://rodrigo.sharpcube.com/2010/04/29/the-day-my-video-card-exploded/">capacitors incident</a>, I decided to take my backups more seriously).</p>
<p>Anyway, one of the things I always wanted (and finally had time) to do was to setup my own OpenVPN server. In case you don&#8217;t know, VPN stands for &#8220;Virtual Private Network&#8221;, and it&#8217;s a way to have your own secure network no matter where you are. Whenever you&#8217;re at a cafe or an hotel and want to make sure no one can take a peek on what you&#8217;re doing (yes, it&#8217;s pretty easy to do that) you <strong>need</strong> a VPN. Having a VPN server can also help you circumvent <a href="http://www.webglossary.co.uk/g/geoblocking/">geoblocking</a>, if that&#8217;s what you&#8217;re up to.</p>
<p>I decided to write this article to share the experience I had configuring my own VPN, specially when I wanted to share the connection with other devices in my network. If that&#8217;s what you want to do, read on and I&#8217;ll try to explain what I did and how I did it.</p>
<p><span id="more-127"></span></p>
<h3>The Server</h3>
<p>If you want to have your own VPN, the first thing you need is an OpenVPN server. You have two options: using your own server or using an OpenVPN service provider. The whole process of setting up the server is out of the scope of this article, but if you have a Linux server you can find <a href="http://library.linode.com/networking/vpn-services/openvpn-ubuntu-10.04-lucid">some great guides</a> on Linode&#8217;s Library. By the way, Linode is a great <a href="http://en.wikipedia.org/wiki/Virtual_private_server">VPS</a> provider (I highly recommend it &#8211; this server is located there), so if you want to have your own server there you can use my <a href="http://www.linode.com/?r=36008b563d8e7d63d86a33c927ad15dc88e44290">referral code</a>.</p>
<p>Another option is to use a VPN service provider. There are both free and paid VPN services, and if all you want is to have a VPN without bothering with server setup, this is the easiest way. <a href="http://code.google.com/p/tunnelblick/wiki/GettingVPNService#VPN_Service_Providers_That_Recommend_Tunnelblick_Exclusively_for">Here&#8217;s a list of some VPN service providers</a> (prices range from $0 to $15 per month, depending on the speed/bandwidth you need).</p>
<h3>The Client</h3>
<p>Okay, so you have your server, now you need a client to connect to your VPN. I&#8217;ll help you setup <a href="http://code.google.com/p/tunnelblick/">Tunnelblick</a> on Mac OS X. Since I never used any VPN client on Windows I can&#8217;t help you there, but if you&#8217;re stuck on Windows I recommend using <a href="http://openvpn.se/">OpenVPN GUI</a>.</p>
<p>The first time you open <strong>Tunnelblick</strong> after installing it will ask for your password. It&#8217;s ok, it needs your password to secure your keys and configuration files (and that&#8217;s very important, since anyone with access to your keys can connect to your VPN server). After that, it will ask if you want to create a sample configuration file. I suppose you already have your config file and keys (that&#8217;s part of the server setup) so  let&#8217;s just ask for it to open the configuration folder, so we can put our files there. If you don&#8217;t have a config file from your server, you can let <strong>Tunnelblick</strong> create one for you. Close the program after that.</p>
<p>Copy your configuration and certificates to the configuration folder. Usually you&#8217;ll need to copy 4 files: <strong>client.conf</strong>, <strong>ca.crt</strong>, <strong>&lt;yourclient&gt;.crt</strong> and <strong>&lt;yourclient&gt;.key</strong>. Rename <strong>client.conf</strong> to the name you want to use to identify your server (i.e. <strong>MyServer.conf</strong>), open it in your favorite text editor and check if it already has at least the following lines (leave the rest untouched):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">remote <span style="color: #000000; font-weight: bold;">&lt;</span>your server address<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>your server port<span style="color: #000000; font-weight: bold;">&gt;</span>
ca ca.crt
cert <span style="color: #000000; font-weight: bold;">&lt;</span>yourclient<span style="color: #000000; font-weight: bold;">&gt;</span>.crt
key <span style="color: #000000; font-weight: bold;">&lt;</span>yourclient<span style="color: #000000; font-weight: bold;">&gt;</span>.key</pre></div></div>

<p>Save your files and launch <strong>Tunnelblick</strong> again. It will add a black tunnel icon to your menu bar. That&#8217;s where it&#8217;ll sit when it&#8217;s running, so you can quickly connect to your OpenVPN server whenever you want to. If you click on its icon, you&#8217;ll see an option to connect to your server, with the same name you used in your config file. But before you connect, let&#8217;s check your current external IP address first: enter <a href="http://www.ip-adress.com/">this site</a>, look for your IP address and write it down.</p>
<p>Ready to connect? Click on the tunnel icon and select <strong>Connect &#8216;YourServer&#8217;</strong>. It&#8217;ll try to connect to your VPN server (if it asks for your password again there&#8217;s nothing wrong, it&#8217;s securing the files you changed. It won&#8217;t ask every time). The menu icon will animate while it&#8217;s connecting, and if it connected successfully the icon will change to an open tunnel. Click on the menu icon again and the first line should read <em>Tunnelblick: 1 connection active</em>. Go back to <a href="http://www.ip-adress.com/">this site</a> and check your IP again. If it changed then congratulations, you&#8217;re already using your VPN connection and all your traffic is going through a secure connection.</p>
<p>If something went wrong and your VPN connection is not working, open <strong>Tunnelblick</strong> menu again and select <em>Details</em>. It will show you a very detailed log file, so you can check for errors and warnings there. And if you are connected to the VPN server but your IP address didn&#8217;t change, the problem is probably in the server: it needs to be configured to forward all VPN traffic and to be the default gateway on the client. All these options are covered in the Linode&#8217;s guide I mentioned earlier. Sure, if you&#8217;re using a VPN service provider you can also contact their support.</p>
<h3>Sharing Your VPN Connection</h3>
<p>So now you are connected to your server and your connection is securely being routed thought the VPN (go ahead and try Hulu, I&#8217;ll wait. I know you want to). But what if you want to use the same VPN in other devices in your network? Sure you can configure <strong>Tunnelblick</strong> in more than one Mac, but some devices like an iPhone or a XBOX 360 don&#8217;t have OpenVPN clients. What can you do about that?</p>
<p>The solution I found is simple: you can share the VPN connection in your Mac and then use your Mac as a gateway for your other devices. The problem is that the OSX&#8217;s native Internet Sharing doesn&#8217;t seem to play nice with OpenVPN. I really tried to use it in every way possible, but it didn&#8217;t work. So I spent some time researching how Internet Sharing works under the hood and I found a solution that is not so simple, but once configured works perfectly.</p>
<p>Open your favorite text editor and create a new file. Paste the following lines on it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
natd <span style="color: #660033;">-interface</span> tun0
ipfw <span style="color: #660033;">-f</span> flush
ipfw add divert natd ip from any to any via tun0
ipfw add pass all from any to any
sysctl <span style="color: #660033;">-w</span> net.inet.ip.forwarding=<span style="color: #000000;">1</span></pre></div></div>

<p>Save it with a name like <strong>natvpn.sh</strong>. Right click the file in Finder, select <em>Get Info</em> and under <em>Permissions</em> mark <em>Execute</em>. Close the <em>Get Info</em> window.</p>
<p>Now what the hell was that all about? Let me break it down to you. We&#8217;re using some native commands to allow your Mac to act like a gateway and forward all the packets to the VPN connection. This is very similar to what OSX&#8217;s Internet Sharing does for you. The name <strong>tun0</strong> is the default interface name <strong>Tunnelblick</strong> will use for your VPN connection, and you can confirm that by opening <strong>Terminal</strong> and typing <strong>ifconfig</strong> while connected to your VPN.</p>
<p>Open <strong>Terminal</strong>. If you&#8217;re not connected to your VPN, connect now. Go to the directory you saved your file (if you saved it in your home folder, you&#8217;re already there) and type:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> .<span style="color: #000000; font-weight: bold;">/</span>natvpn.sh</pre></div></div>

<p>You&#8217;ll need to replace <strong>natvpn.sh</strong> with the name you saved your file. It&#8217;ll ask for your password, type it and you&#8217;ll see something similar to this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Flushed all rules.
00100 divert <span style="color: #000000;">8668</span> ip from any to any via tun0
00200 allow ip from any to any
net.inet.ip.forwarding: <span style="color: #000000;">0</span> -<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">1</span></pre></div></div>

<p>It worked: your Mac is already a gateway! Now all you have to do is go to the device you want to use with the VPN connection and, under its network settings, change the default gateway to your Mac&#8217;s IP address. In most devices, to change the default gateway you&#8217;ll also need to configure it to use Static IP (my iPhone needed, for example). Just copy the same IP address, subnet mask and DNS server it&#8217;s currently using and change only the gateway to your Mac&#8217;s IP address. Oh, and if you don&#8217;t know your Mac&#8217;s IP address go to <strong>Preferences</strong>, open <strong>Network</strong> and select your network connection. In the right panel it&#8217;ll show your IP address under <strong>Status</strong>.</p>
<p>Test your device by going to the <a href="http://www.ip-adress.com/">same site</a> again and it should show you the server&#8217;s IP address. Congratulations, enjoy your new secure VPN connection!</p>
<h3>Conclusion</h3>
<p>As you can see, setting up a VPN connection is pretty simple. Sharing it might be a little more complicated, but now that it&#8217;s configured all you have to do is open <strong>Terminal</strong> and type <strong>sudo ./natvpn.sh</strong> while connected to the VPN everytime you want to share it. It&#8217;s not automatic, but it works pretty well. And of course, if all you want is to use the VPN on your Mac, then you only have to connect using <strong>Tunnelblick</strong> and you&#8217;re done.</p>
<p>This guide assumes you have at least a little experience using the terminal. If you don&#8217;t, you may find yourself a little lost in some parts, especially if you want to share your VPN connection. If that&#8217;s the case, feel free to leave a comment below and I promise I&#8217;ll try to help you!</p>
<h3>Troubleshooting</h3>
<p>The method I described above doesn&#8217;t work together with OSX Internet Sharing. So check if you have it enabled (under Preferences, go to Sharing) and disable it.</p>
<p>If you can&#8217;t find the option in Finder to make the script executable, you can also do it in Terminal. Just type <code>chmod +x natvpn.sh</code>.</p>
<p>Be sure to save the script in TextEdit (or your preferred editor) as a plain text file, not as rich text. You can check this by typing <code>cat natvpn.sh</code> in Terminal. If you see garbage instead of the script, the file was saved as rich text.</p>
<p>If you get the error &#8220;Address already in use&#8221; from natd when running the script, it&#8217;s because you already have natd running, and only one instance can be active. Check if you didn&#8217;t leave OSX Internet Sharing enabled (you have to disable it) or try to run the following code in the Terminal to see what app is running it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ps</span> aux <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> natd</pre></div></div>

<p>When configuring your client device (the one which will be using your Mac&#8217;s connection) set the DNS servers to external addresses. You can use, for example, Google DNS (IPs 8.8.8.8 and 8.8.4.4) (thanks Damian).</p>
<p>If you&#8217;re using a PPTP VPN interface (OSX VPN Client) instead of OpenVPN you need to do a few additional steps. First, add a line <code>IPFORWARDING=-YES-</code> in the file <code>/etc/hostconfig</code>, then change the <code>natd -interface tun0</code> line in the script with (thanks Zantiss):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">natd -same_ports -use_sockets -unregistered_only <span style="color: #660033;">-dynamic</span> <span style="color: #660033;">-interface</span> ppp0 -clamp_mss</pre></div></div>

<p>There are some reports of speed issues when using a PPTP VPN, but I don&#8217;t have access to a PPTP VPN so I can&#8217;t confirm it.</p>
<p>If your VPN server doesn&#8217;t register itself as your default gateway, you can override this in your client configuration file. Just add the line <code>redirect-gateway def1</code> to the file (thanks Jon).</p>
<p>If you want to turn VPN sharing off, create another script called <code>natvpnoff.sh</code> (or something similar) and put the following lines inside it (thanks Yohann):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #c20cb9; font-weight: bold;">killall</span> natd
ipfw <span style="color: #660033;">-f</span> flush
sysctl <span style="color: #660033;">-w</span> net.inet.ip.forwarding=<span style="color: #000000;">0</span></pre></div></div>

<p>After saving, run the script with <code>sudo natvpnoff.sh</code>. You could also reboot your machine to disable VPN sharing, since none of the changes in the script is permanent.</p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/wpRjPMzRZVE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2010/06/20/using-and-sharing-a-vpn-connection-on-your-mac/feed/</wfw:commentRss>
		<slash:comments>284</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2010/06/20/using-and-sharing-a-vpn-connection-on-your-mac/</feedburner:origLink></item>
		<item>
		<title>The Day My Video Card Exploded</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/lRUZ3c7towE/</link>
		<comments>http://rodrigo.sharpcube.com/2010/04/29/the-day-my-video-card-exploded/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 04:53:26 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Capacitors]]></category>
		<category><![CDATA[Card]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=125</guid>
		<description><![CDATA[Ok, I may be exaggerating a bit. My video card didn&#8217;t literally explode. Here&#8217;s what happened: Yesterday I was working when my computer froze. &#8220;Well, sometimes it happens&#8221;, I thought, so I tried rebooting it. It appeared to start normally, then nothing. Mac OS just froze at the login screen, and trying to boot Windows [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, I may be exaggerating a bit. My video card didn&#8217;t <em>literally</em> explode. Here&#8217;s what happened:</p>
<p>Yesterday I was working when my computer froze. &#8220;Well, sometimes it happens&#8221;, I thought, so I tried rebooting it. It appeared to start normally, then nothing. Mac OS just froze at the login screen, and trying to boot Windows gave me a BSOD. I managed to boot OSX in safe mode and everything appeared to be working: my hard drives were OK, apps were running, no errors. So I turned off the computer and tried to turn it on again 10 minutes later. This is what I saw:</p>
<div class="picturebox aligncenter" style="width: 500px;"><img src="http://rodrigo.sharpcube.com/wp-content/uploads/2010/04/garbage.jpg" alt="garbage.jpg" border="0" width="500" /><br />
Well, maybe my monitor is out of tune.
</div>
<p>&#8220;So it must be something with the video card&#8221;, I thought. I opened my computer case, popped the video card out, and started inspecting it. Soon enough I found the culprit:</p>
<div class="picturebox aligncenter" style="width: 500px;"><img src="http://rodrigo.sharpcube.com/wp-content/uploads/2010/04/blown_up.jpg" alt="blown_up.jpg" border="0" width="500" /><br />
Yep. Three beautifully blown up capacitors.
</div>
<p>At first I panicked. This is my work computer, it had to be working again ASAP. I started searching online for a new video card, but since I live in a (kinda) small city, video cards are not only really expensive here, they&#8217;re also hard to find. But I had no option: I needed it working, so I was convinced to get a new video card first thing in the morning on the next day.</p>
<p>A couple of minutes later I tried to google &#8220;blown up capacitor&#8221; just to see what kind of results I&#8217;d get, and I noticed this is quite common. These capacitors are pretty bad quality and are prone to explode, specially in the video card I have (it&#8217;s a XFX Geforce 8600GT): the ones that blew up sit right in front of the cooler&#8217;s air escape, so the cooler is pretty much blowing hot air on them all the time (what a great design, huh?)</p>
<p>I found some people saying that they&#8217;re pretty easy (and cheap) to replace, so I decided to give it a try. What the heck, the card was already dead anyway. So I woke up this morning, went to a local electronics store and bought three capacitors to replace them. I tried to do it myself, but my soldering iron was not good enough for the job (I could fry the card), so I ended up going to one of these places where they fix TVs and stuff and asked them to replace the capacitors for me. After a few minutes they gave me my card back with the new capacitors:</p>
<div class="picturebox aligncenter" style="width: 500px;"><img src="http://rodrigo.sharpcube.com/wp-content/uploads/2010/04/new.jpg" alt="new.jpg" border="0" width="500" /><br />
<strong>Now</strong> we&#8217;re talking.
</div>
<p>Guess what? I put the card back into the computer and everything is working again! I could not believe it: I did decide to try replacing the capacitors, but I was pretty much expecting nothing, already prepared to spend more than $250 in a new video card. So I ran a few tests and it all seemed to be ok. I worked all day on the computer and it&#8217;s perfect, as if nothing happened.</p>
<p>Total cost to repair the video card: about $3 for the capacitors, and about $2 for the guy who soldered them for me. And, of course, the satisfaction of knowing that what seemed like a stupid idea did actually work. </p>
<p>Now just try to imagine how many video cards that could be fixed with five bucks and a few minutes of work end up in the garbage&#8230;</p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/lRUZ3c7towE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2010/04/29/the-day-my-video-card-exploded/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2010/04/29/the-day-my-video-card-exploded/</feedburner:origLink></item>
		<item>
		<title>The Inevitable Hello World</title>
		<link>http://feeds.sharpcube.com/~r/rodrigo_sharpcube/~3/rZspNvwYFV0/</link>
		<comments>http://rodrigo.sharpcube.com/2010/04/27/hello-world/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 05:36:08 +0000</pubDate>
		<dc:creator>Rodrigo Sieiro</dc:creator>
				<category><![CDATA[Meta]]></category>
		<category><![CDATA[First Post]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://rodrigo.sharpcube.com/?p=113</guid>
		<description><![CDATA[I know, it&#8217;s a cliché to start a software development blog with &#8220;Hello World&#8221;, but I couldn&#8217;t resist. Anyway, welcome to my blog. My name is Rodrigo Sieiro and I&#8217;m a software developer. If you want to know more about me and what this blog is about, check the About page. Go ahead, I&#8217;ll wait. [...]]]></description>
			<content:encoded><![CDATA[<p>I know, it&#8217;s a cliché to start a software development blog with &#8220;Hello World&#8221;, but I couldn&#8217;t resist. Anyway, welcome to my blog. My name is Rodrigo Sieiro and I&#8217;m a software developer. If you want to know more about me and what this blog is about, check the <a href="http://rodrigo.sharpcube.com/about/">About</a> page. Go ahead, I&#8217;ll wait.</p>
<p>Back? Great. I created this blog (and by &#8220;created&#8221; I mean the subdomain and the template) in August 2009, but I never really started it until now. Usually I&#8217;m just too critical about myself and I always think that everything I write is not &#8220;good enough&#8221; to publish. But then I realized that I&#8217;ll never get to a point where I consider my posts to be &#8220;good enough&#8221; if I don&#8217;t start writing. So I decided to start posting anyway, hoping that I&#8217;ll get better with time.</p>
<p>My plan is to start with at least one post a week. If I manage to do that for a while, then I can start writing more. It has been almost a year since I started my company and I really regret not documenting all the ups and downs I&#8217;ve been through. Well, there&#8217;s nothing I can do about the past, but I can start writing right now. And that&#8217;s exactly what I&#8217;m doing!</p>
<img src="http://feeds.feedburner.com/~r/rodrigo_sharpcube/~4/rZspNvwYFV0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://rodrigo.sharpcube.com/2010/04/27/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://rodrigo.sharpcube.com/2010/04/27/hello-world/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 1.031 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-02-13 19:53:00 --><!-- Compression = gzip -->

