<?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>SteveLove.org &#187; Ubuntu</title>
	<atom:link href="http://stevelove.org/category/ubuntu/feed/" rel="self" type="application/rss+xml" />
	<link>http://stevelove.org</link>
	<description>Code, Literature and Other Worthless Pursuits</description>
	<lastBuildDate>Mon, 28 Jun 2010 21:53:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Clonezilla is pretty much awesome at system recovery</title>
		<link>http://stevelove.org/2009/07/11/clonezilla-is-pretty-much-awesome-at-system-recovery/</link>
		<comments>http://stevelove.org/2009/07/11/clonezilla-is-pretty-much-awesome-at-system-recovery/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 19:16:08 +0000</pubDate>
		<dc:creator>Steve Love</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[Clonezilla]]></category>
		<category><![CDATA[grub]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[system]]></category>
		<category><![CDATA[utility]]></category>

		<guid isPermaLink="false">http://stevelove.org/?p=114</guid>
		<description><![CDATA[Cross-platform Clonezilla is a great tool for handling your system backup and system restore needs. Just tested it out using the Live CD on my laptop and found it to be very fast and very successful.
Initially I used the stable release of Clonezilla to back up my laptop&#8217;s entire hard drive to a USB external [...]]]></description>
			<content:encoded><![CDATA[<p>Cross-platform <a href="http://clonezilla.org">Clonezilla</a> is a great tool for handling your system backup and system restore needs. Just tested it out using the Live CD on my laptop and found it to be very fast and very successful.<span id="more-114"></span></p>
<p>Initially I used the stable release of Clonezilla to back up my laptop&#8217;s entire hard drive to a USB external hard drive. No problems at all. However, I hit a minor snag when restoring the system with the stable release in that it failed to re-install grub. Oops. Not to worry though, Clonezilla has an &#8220;alternative&#8221; release based off Ubuntu (the stable release is built on standard Debian). Since I happen to be running Ubuntu, I made a new Live CD with the alternative Ubuntu release and once again tried the system restore. This time it worked perfectly and my system is exactly as it was at the time I backed it up.</p>
]]></content:encoded>
			<wfw:commentRss>http://stevelove.org/2009/07/11/clonezilla-is-pretty-much-awesome-at-system-recovery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading to VirtualBox 3.0 causes Linux guest to hang [Solved]</title>
		<link>http://stevelove.org/2009/07/08/upgrading-to-virtualbox-3-0-causes-linux-guest-to-hang-solved/</link>
		<comments>http://stevelove.org/2009/07/08/upgrading-to-virtualbox-3-0-causes-linux-guest-to-hang-solved/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 03:48:36 +0000</pubDate>
		<dc:creator>Steve Love</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://stevelove.org/?p=109</guid>
		<description><![CDATA[I got to work a little early this morning and decided to upgrade to the new VirtualBox 3.0, which I use to run Ubuntu 9.04 as a guest on my 64-bit Windows Vista host machine. 
The upgrade was simple as always and I experienced no issues &#8230; until I tried to boot up my Ubuntu [...]]]></description>
			<content:encoded><![CDATA[<p>I got to work a little early this morning and decided to upgrade to the new <a href="http://www.virtualbox.org/">VirtualBox 3.0</a>, which I use to run Ubuntu 9.04 as a guest on my 64-bit Windows Vista host machine. </p>
<p>The upgrade was simple as always and I experienced no issues &#8230; until I tried to boot up my Ubuntu VM. It appeared to hang during boot up, and finally ended in a kernel panic. Every time.</p>
<p>There&#8217;s an easy fix, however, which I found <a href="http://forums.virtualbox.org/viewtopic.php?f=6&#038;t=19395#p83847">here</a> after a quick Google search. The solution is to change the VM settings for the network adapter from &#8220;PCnet-FAST III&#8221; to &#8220;Intel PRO/1000 MT Desktop&#8221;. </p>
]]></content:encoded>
			<wfw:commentRss>http://stevelove.org/2009/07/08/upgrading-to-virtualbox-3-0-causes-linux-guest-to-hang-solved/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to install and set up Adobe Flex SDK on Ubuntu linux</title>
		<link>http://stevelove.org/2009/05/14/how-to-install-and-set-up-adobe-flex-sdk-on-ubuntu-linux/</link>
		<comments>http://stevelove.org/2009/05/14/how-to-install-and-set-up-adobe-flex-sdk-on-ubuntu-linux/#comments</comments>
		<pubDate>Fri, 15 May 2009 03:41:14 +0000</pubDate>
		<dc:creator>Steve Love</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://stevelove.org/?p=31</guid>
		<description><![CDATA[With the open source Adobe Flex SDK, developers using any operating system and any text editor or IDE can create rich Internet applications that compile into SWF files. This guide is for those wanting to install and set up the Flex SDK on Ubuntu linux. 
What do you need to install Flex on Ubuntu?

The Flex [...]]]></description>
			<content:encoded><![CDATA[<p>With the open source <a href="http://en.wikipedia.org/wiki/Adobe_Flex">Adobe Flex</a> SDK, developers using any operating system and any text editor or IDE can create rich Internet applications that compile into SWF files. This guide is for those wanting to install and set up the Flex SDK on Ubuntu linux. <span id="more-31"></span></p>
<h3>What do you need to install Flex on Ubuntu?</h3>
<ol>
<li>The <a href="http://www.adobe.com/products/flex/flexdownloads/">Flex SDK</a></li>
<li>Sun Java (needed for compiling the SWF binaries)</li>
</ol>
<h3>Set up and install Flex</h3>
<p>Step 1. If you haven&#8217;t already, install Java. (If you aren&#8217;t sure, go ahead and try this step anyway.) First open up a terminal (Accessories menu > Terminal) and type the following:</p>
<pre class="brush: plain;">sudo apt-get install java-package sun-java6-jdk</pre>
<p>This will take several minutes while the packages download and install. You&#8217;ll also need to agree to Sun&#8217;s license.</p>
<p>Step 2. Download the <a href="http://www.adobe.com/products/flex/flexdownloads/">Flex SDK</a>. The rest of this guide will assume you saved the SDK to your desktop: <span class="code">~/Desktop</span>.</p>
<p>Step 3. We need to create a directory for the Flex SDK. In a terminal window, enter the following:</p>
<pre class="brush: plain;">sudo mkdir /opt/flex</pre>
<p>The &#8220;opt&#8221; directory is generally where optional application software packages live. (More info on the <a href="http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard">linux file system</a>.) All we did here is make a new &#8220;flex&#8221; directory inside &#8220;opt&#8221;.</p>
<p>Step 4. Now we need to unzip the Flex SDK. Type the following in a terminal window:</p>
<pre class="brush: plain;">
cd ~/Desktop
unzip flex_sdk_4.zip -d tempflex
</pre>
<p>What this does is unzip the contents of your download into a new and temporary directory on your Desktop called &#8220;tempflex&#8221;.</p>
<p>Step 5. After that&#8217;s complete, we need to move these files to &#8220;opt/flex&#8221; which we&#8217;ve already prepared for the SDK. Type the following in a terminal window:</p>
<pre class="brush: plain;">sudo mv tempflex/* /opt/flex/</pre>
<p>This will move the contents of &#8220;tempflex&#8221; into &#8220;opt/flex&#8221;. If you want to make sure you moved everything, you can type the following into a terminal window:</p>
<pre class="brush: plain;">
cd /opt/flex
ls
</pre>
<p>You should see a list of all the files in the directory.</p>
<p>Step 6. Last step. All we need to do now is let Ubuntu know where the new Flex compiler lives. Type the following in a terminal window to open up &#8220;~/.bashrc&#8221; in a text editor:</p>
<pre class="brush: plain;">gedit ~/.bashrc</pre>
<p>The text editor will open your ~/.bashrc profile and we only need to add one line (I added it at the bottom of the file, but I&#8217;m not sure it matters).</p>
<pre class="brush: plain;">export PATH=/opt/flex/bin:$PATH</pre>
<p>Save the file and close the text editor. Then exit all open terminal windows before opening a new one. This should ensure that your terminal loads the path that we just added.</p>
<p>You should now be able to compile your Flex projects with the &#8220;mxmlc&#8221; compiler command. To make sure, type the following in a terminal window to bring up the &#8220;help&#8221;:</p>
<pre class="brush: plain;">mxmlc --help</pre>
<p>Looks good? Great. You&#8217;re all set. Happy Flex-developing.</p>
]]></content:encoded>
			<wfw:commentRss>http://stevelove.org/2009/05/14/how-to-install-and-set-up-adobe-flex-sdk-on-ubuntu-linux/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>How To: Yahoo and the Simple OpenID PHP Class</title>
		<link>http://stevelove.org/2008/08/24/how-to-yahoo-and-the-simple-openid-php-class/</link>
		<comments>http://stevelove.org/2008/08/24/how-to-yahoo-and-the-simple-openid-php-class/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 21:58:29 +0000</pubDate>
		<dc:creator>Steve Love</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://stevelove.org/?p=17</guid>
		<description><![CDATA[[Note: This post contains outdated information. Please visit the project page here for the latest information.]
I&#8217;ve been working on OpenID a lot lately and I&#8217;ve latched on to a great starter PHP class called, obviously enough, Simple OpenID PHP Class (Simple OpenID). It&#8217;s easy enough to implement, but I quickly noticed that it didn&#8217;t work [...]]]></description>
			<content:encoded><![CDATA[<p><big><b>[Note: This post contains outdated information. Please visit the project page <a href="http://stevelove.org/projects/dope-openid/">here</a> for the latest information.]</b></big></p>
<p>I&#8217;ve been working on OpenID a lot lately and I&#8217;ve latched on to a great starter PHP class called, obviously enough, <a href="http://www.phpclasses.org/browse/package/3290.html">Simple OpenID PHP Class</a> (Simple OpenID). It&#8217;s easy enough to implement, but I quickly noticed that it didn&#8217;t work with Yahoo (among others). Basically it would return an error saying it couldn&#8217;t find an OpenID server at Yahoo. <span id="more-17"></span></p>
<p>At this point, I thought about switching to the very full featured <a href="http://openidenabled.com/php-openid/">JanRain PHP OpenID library</a> but it&#8217;s way more than I need right now. So I decided to stick it out with Simple OpenID and see if I couldn&#8217;t get it working like it should. In the end, I was able to get it working with Yahoo. I&#8217;ll show you how. If you find things aren&#8217;t coming together like they should, you can <a href="http://stevelove.org/projects/dope-openid/">download</a> the version of Simple OpenID that I&#8217;m now using.</p>
<p>What You&#8217;ll Need:</p>
<ul>
<li><a href="http://www.phpclasses.org/browse/package/3290.html">Simple OpenID</a> (requires cURL) Link points to the original file. Download my updated version <a href="http://stevelove.org/projects/dope-openid/">here</a>.</li>
<li>The PHP Yadis Library. This tutorial assumes you&#8217;re using the stand-alone download <a href="http://openidenabled.com/files/php-openid/files/PHP-yadis-1.0.2.tar.gz">here</a>.</li>
</ul>
<p>Summary:<br />
As it currently stands, Simple OpenID is built more or less to <a href="http://openid.net/specs/openid-authentication-1_1.html">OpenID 1.1 specifications</a>. What we&#8217;re going to do is add support for the <a href="http://openid.net/specs/openid-authentication-2_0.html">2.0 specifications</a>, which Yahoo requires. </p>
<p>It is assumed that you already have Simple OpenID installed and working with at least a few providers (Technorati and AOL seem to work right out of the box). If you need help getting it installed, look at the comments in the class itself, or check out the example included with the class.</p>
<p>Caveat:<br />
To be honest, I haven&#8217;t read the 2.0 specifications in full, so I may have missed some requirements here and there. I&#8217;ve added in the ones that I noticed and knew wouldn&#8217;t take much time to implement in a somewhat proper manner. The scope of this tutorial is only to get Simple OpenID working with Yahoo, not filling out every detail the class currently lacks.</p>
<p>Setup:<br />
First up is Yadis (if you&#8217;re interested, there&#8217;s more info <a href="http://yadis.org/wiki/Main_Page">here</a> and <a href="http://en.wikipedia.org/wiki/Yadis">here</a>). Extract the Yadis library that you downloaded. Find the Services directory and copy it to the same directory on your server where you have Simple OpenID. Something like this:</p>
<p><span class="code"><br />
www/Services/<br />
www/class.openid.php<br />
</span></p>
<p>All done? Okay, let&#8217;s get started!</p>
<p>At the time of this writing, the latest version of Simple OpenID is <span class="code">class.openid.v3.php</span>, so we&#8217;ll be working with that. Open it up in your editor of choice now.</p>
<p>Stop right there at line 1. We&#8217;re interested in compatibility here, people. Not only could that PHP short tag be mistaken for an XML opening tag, but it won&#8217;t work on a PHP installation that has short tags disabled. Change it to the full tag. It&#8217;s just three extra characters. Do it.</p>
<pre class="brush: php;">
&lt;?php
</pre>
<p>Now let&#8217;s add in the Yadis classes by adding the following on line 66.</p>
<pre class="brush: php;">
require_once 'Services/Yadis/Yadis.php';
</pre>
<p>Simple OpenID is currently equipped to locate an OpenID server by sending a request to the identity URL provided by the user and parsing the HTML response that&#8217;s returned. Yahoo doesn&#8217;t work this way. We have to use Yadis discovery to locate the server. Edit the <span class="code">GetOpenIDServer</span> method so that it looks like the code below.</p>
<pre class="brush: php;">
function GetOpenIDServer(){

    //Try Yadis Protocol discovery first
    $http_response = array();
    $fetcher = Services_Yadis_Yadis::getHTTPFetcher();
    $yadis_object = Services_Yadis_Yadis::discover($this-&gt;openid_url_identity,
                                                $http_response, $fetcher);

    // Yadis object is returned if discovery is successful
    if($yadis_object != null){
        $service_list = $yadis_object-&gt;services();
        $types = $service_list[0]-&gt;getTypes();
        $servers = $service_list[0]-&gt;getURIs();
        $delegates = $service_list[0]-&gt;getElements('openid:Delegate');
    }else{ // Else try HTML discovery
        $response = $this-&gt;CURL_Request($this-&gt;openid_url_identity);
        list($servers, $delegates) = $this-&gt;HTML2OpenIDServer($response);
    }
    if (count($servers) == 0){
        $this-&gt;ErrorStore('OPENID_NOSERVERSFOUND');
        return false;
    }
    if (isset($types[0])
      &amp;&amp; ($types[0] != &quot;&quot;)){
	$this-&gt;SetServiceType($types[0]);
    }
    if (isset($delegates[0])
      &amp;&amp; ($delegates[0] != &quot;&quot;)){
        $this-&gt;SetIdentity($delegates[0]);
    }
    $this-&gt;SetOpenIDServer($servers[0]);
    return $servers[0];
}
</pre>
<p>If you look at line 278 now, you&#8217;ll see we added a call to a method named <span class="code">SetServiceType</span>. Since there are still providers out there using OpenID 1.1 (i.e. livejournal.com) we need to make sure we can handle the specifications for whatever we come across. We&#8217;ll have to set the service type based on the version being used. Let&#8217;s add the <span class="code">SetServiceType</span> method at line 85.</p>
<pre class="brush: php;">
function SetServiceType($a){
    // Hopefully the provider is using OpenID 2.0 but let's check
    // the protocol version in order to handle backwards compatibility.
    // Probably not the best method, but it works for now.
    if(stristr($a, &quot;2.0&quot;)){
        $ns = &quot;http://specs.openid.net/auth/2.0&quot;;
        $version = &quot;2.0&quot;;
    }
    else if(stristr($a, &quot;1.1&quot;)){
        $ns = &quot;http://openid.net/signon/1.1&quot;;
        $version = &quot;1.1&quot;;
    }else{
        $ns = &quot;http://openid.net/signon/1.0&quot;;
        $version = &quot;1.0&quot;;
    }
    $this-&gt;openid_ns = $ns;
    $this-&gt;version   = $version;
}
</pre>
<p>What this does is check the service type we found during discovery and set the namespace (<span class="code">openid.ns</span>) and version appropriately. At this point, if we test what we have, we&#8217;ll be able to find Yahoo&#8217;s OpenID server address and redirect our user there to authenticate. But instead of being asked to login, our user will get this message from Yahoo:</p>
<blockquote><p>Sorry! You will not be able to login to this website as it is using an older version of the the OpenID technology. Yahoo! only supports OpenID 2.0 because it is more secure. For more information, check out the OpenID documentation at Yahoo! Developer Network.</p></blockquote>
<p>So it seems there&#8217;s more to OpenID 2.0 support than just adding in Yadis discovery. Don&#8217;t bother checking out the OpenID documentation at Yahoo! Developer Network, though. The only useful thing there is a link to the specifications for OpenID 2.0. After glancing through the specs, we find out we need to send some information to Yahoo as part of the URL query string.</p>
<p>If you look at the GetRedirectURL method, you&#8217;ll see on lines 307-311 we&#8217;re setting up our parameters array with the following: <span class="code">openid.return_to, openid.mode, openid.identity, openid.trust_root</span>. Lines 313-320 add the request for any <span class="code">sreg</span> info you want to get back from the OpenID provider.</p>
<p>That&#8217;s enough for the 1.1 specs, but not for 2.0. If, as is the case with Yahoo, we&#8217;re dealing with a 2.0 provider, we also need to send <span class="code">openid.ns</span> and <span class="code">openid.claimed_id</span>. In addition, the specs say that <span class="code">openid.trusted_root</span> has been renamed <span class="code">openid.realm</span> for 2.0. Let&#8217;s add our conditional code and change the <span class="code">GetRedirectURL</span> method to the following.</p>
<pre class="brush: php;">
function GetRedirectURL(){
    $params = array();
    $params['openid.return_to'] = urlencode($this-&gt;URLs['approved']);
    if($this-&gt;version == &quot;2.0&quot;){
        $params['openid.ns'] = urlencode($this-&gt;openid_ns);
        $params['openid.claimed_id'] = urlencode($this-&gt;openid_url_identity);
        $params['openid.realm'] = urlencode($this-&gt;URLs['trust_root']);
    }else{
        $params['openid.trust_root'] = urlencode($this-&gt;URLs['trust_root']);
    }
    $params['openid.mode'] = 'checkid_setup';
    $params['openid.identity'] = urlencode($this-&gt;openid_url_identity);

    if (isset($this-&gt;fields['required'])
      &amp;&amp; (count($this-&gt;fields['required']) &gt; 0)) {
        $params['openid.sreg.required'] = implode(',',$this-&gt;fields['required']);
    }
    if (isset($this-&gt;fields['optional'])
      &amp;&amp; (count($this-&gt;fields['optional']) &gt; 0)) {
        $params['openid.sreg.optional'] = implode(',',$this-&gt;fields['optional']);
    }
    return $this-&gt;URLs['openid_server'] . &quot;?&quot;. $this-&gt;array2url($params);
}
</pre>
<p>As you can see above, the value of <span class="code">openid.claimed_id</span> is the same as <span class="code">openid.identity</span>.</p>
<p>If you try our code now, you should be able to reach Yahoo&#8217;s OpenID login server. Great! Log in if you&#8217;re not already, and you&#8217;ll see a button that says &#8220;Let Me In.&#8221; (You&#8217;ll probably also see a scary warning message that says your website hasn&#8217;t confirmed its identity with Yahoo. Don&#8217;t worry about this for now; we&#8217;ll take care of it later.)</p>
<p>Click the &#8220;Let Me In&#8221; button and you&#8217;ll be taken back to the URL you specified as the <span class="code">return_to</span> address. But for some reason, there&#8217;s an error message that says &#8220;Could not validate the OpenID at http://yahoo.com/&#8221;. This message comes from the <span class="code">ValidateWithServer</span> method, so something must be going wrong here.</p>
<p>When we made our first request to Yahoo, we sent some parameters in the URL. When the user clicks &#8220;Let Me In&#8221;, Yahoo sends its own parameters appended to the <span class="code">return_to</span> address. You can see them if you look at the URL where you got the error message. If you look closely, you&#8217;ll see one of the parameters returned is <span class="code">openid.signed</span>. The value is a comma-separated list of parameters that Yahoo wants us to validate. Basically, Yahoo wants us to send these data back so they can let us know if anything has been tampered with in transit.</p>
<p>If you look at lines 341-345, you can see that we&#8217;re building another array of parameters that we&#8217;re going to validate with Yahoo. <span class="code">openid.assoc_handle, openid.signed</span> and <span class="code">openid.sig</span> are all declared outright. Then beginning on line 347, you can see we&#8217;re taking the comma-separated list, the signed parameters returned with <span class="code">openid_signed</span>, and replacing all instances of &#8220;<span class="code">sreg.</span>&#8221; with &#8220;<span class="code">sreg_</span>&#8220;, then storing it as an array (<span class="code">$arr_signed</span>). Since the comma-separated list contains variables that are passed in the URL, PHP will automatically add them in our global <span class="code">$_GET</span> array. But anything like <span class="code">openid.sreg.fullname</span> will become <span class="code">$_GET['openid_sreg_fullname']</span> when PHP parses the variables.</p>
<p>On line 348, there&#8217;s a for loop that goes through each of the signed parameters and uses logic to grab the value from <span class="code">$_GET['openid_sreg_fullname']</span> and store it as <span class="code">$params['openid.sreg.fullname']</span>.</p>
<p>And finally line 355 sets <span class="code">openid.mode</span> to &#8220;<span class="code">check_authentication</span>&#8221; and adds it to our array of parameters.</p>
<p>So if the for loop adds all of the signed parameters that Yahoo gives us, why are we getting an error? Well, let&#8217;s look at the signed parameters Yahoo is asking for.</p>
<ul>
<li>assoc_handle</li>
<li>claimed_id</li>
<li>identity</li>
<li>mode</li>
<li>ns</li>
<li>ns.pape</li>
<li>op_endpoint</li>
<li>pape.auth_policies</li>
<li>pape.nist_auth_level</li>
<li>response_nonce</li>
<li>return_to</li>
<li>signed</li>
</ul>
<p>If you recall, the variable names containing periods or dots are going to be converted to underscores when added to the <span class="code">$_GET</span> array. Line 347 takes care of any names taking the form &#8220;<span class="code">sreg.</span>&#8221; but as you can see, we need to do something with names containing &#8220;<span class="code">ns.</span>&#8221; and &#8220;<span class="code">pape.</span>&#8221; as well. Let&#8217;s rewrite the <span class="code">ValidateWithServer</span> method to reflect this.</p>
<pre class="brush: php;">
function ValidateWithServer(){

    $params             = array();
    $arr_underscores    = array('ns_', 'pape_', 'sreg_');
    $arr_periods        = array('ns.', 'pape.', 'sreg.');
    $arr_getSignedKeys  = explode(&quot;,&quot;,str_replace($arr_periods, $arr_underscores, $_GET['openid_signed']));

    // Send only required parameters to confirm validity
    foreach($arr_getSignedKeys as $key){
        $paramKey = str_replace($arr_underscores, $arr_periods, $key);
        $params[&quot;openid.$paramKey&quot;] = urlencode($_GET[&quot;openid_$key&quot;]);
    }
    if($this-&gt;openid_version != &quot;2.0&quot;){
        $params['openid.assoc_handle'] = urlencode($_GET['openid_assoc_handle']);
        $params['openid.signed'] = urlencode($_GET['openid_signed']);
    }
    $params['openid.sig'] = urlencode($_GET['openid_sig']);
    $params['openid.mode'] = &quot;check_authentication&quot;;

    $openid_server = $this-&gt;GetOpenIDServer();
    if ($openid_server == false){
        return false;
    }
    $response = $this-&gt;CURL_Request($openid_server,'POST',$params);
    $data = $this-&gt;splitResponse($response);

    if ($data['is_valid'] == &quot;true&quot;) {
        return true;
    }else{
        return false;
    }
}
</pre>
<p>If you try the code now, you should have a successful validation. Excellent!</p>
<p>But &#8230; what about that scary warning message we saw on the Yahoo OpenID endpoint?</p>
<p>To get rid of that, you need to create an XRDF file to let Yahoo know who you are. Create a file called &#8220;<span class="code">yadis.xrdf</span>&#8221; and place it somewhere on your server. The important part of this file is that you tell it where your <span class="code">return_to</span> URL is. The file should look like this.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;xrds:XRDS
    xmlns:xrds=&quot;xri://$xrds&quot;
    xmlns:openid=&quot;http://openid.net/xmlns/1.0&quot;
    xmlns=&quot;xri://$xrd*($v*2.0)&quot;&gt;
    &lt;XRD&gt;
        &lt;Service priority=&quot;0&quot;&gt;
            &lt;Type&gt;http://specs.openid.net/auth/2.0/return_to&lt;/Type&gt;
            &lt;URI&gt;http://yourdomain.com:80/path-to/your_return_to.php&lt;/URI&gt;
        &lt;/Service&gt;
    &lt;/XRD&gt;
&lt;/xrds:XRDS&gt;
</pre>
<p>All you need to do now is send a header from your site that reveals the location of your XRDF file. <del datetime="2009-07-04T23:33:03+00:00">I&#8217;m not certain on this, but it appears that you need to send this header from the index page of your OpenID login area. For example, if your login form is at <span class="code">http://example.com/openid/login.php</span>, the header should be sent from <span class="code">http://example.com/openid/index.php</span> in order for Yahoo to find it. Add the following code to the top of your index page.</del> This header must be sent from the root of the URL you specified as your &#8220;trust root&#8221;. There cannot be any output before this header or it won&#8217;t work. It must be the very first thing, probably just after the opening PHP tag.</p>
<pre class="brush: php;">
header('X-XRDS-Location:http://yourdomain.com/path-to/yadis.xrdf');
</pre>
<p>What&#8217;s next?</p>
<p>There&#8217;s plenty more to do for the 2.0 specs. For example, while an OpenID could take the form of &#8220;<span class="code">http://example.com/user</span>&#8220;, it could also look like &#8220;<span class="code">xri://=john.smith</span>&#8221; or something equally strange. XRI support is something else that has been added to the 2.0 specs. All we need to do is add some logic to handle these types of identities. Since this kind of logic already exists in the <span class="code">SetIdentity</span> method, let&#8217;s add it there.</p>
<pre class="brush: php;">
function SetIdentity($a){ 	// Set Identity URL

    $xriIdentifiers = array('=', '$', '!', '@', '+');
    $xriProxy = 'http://xri.net/';

    // Is this an XRI string?
    // Check for &quot;xri://&quot; prefix or XRI Global Constant Symbols
    if (stripos($a, 'xri://') || in_array($a[0], $xriIdentifiers)){
        // Attempts to convert an XRI into a URI by removing the &quot;xri://&quot; prefix and
        // appending the remainder to the URI of an XRI proxy such as &quot;http://xri.net&quot;
        if (stripos($a, 'xri://') == 0) {
            if (stripos($a, 'xri://$ip*') == 0) {
                $a = substr($a, 10);
            } elseif (stripos($a, 'xri://$dns*') == 0) {
                $a = substr($a, 11);
            } else {
                $a = substr($a, 6);
            }
        }
            $a = $xriProxy.$a;
    }

    if ((stripos($a, 'http://') === false)
      &amp;&amp; (stripos($a, 'https://') === false)){
        $a = 'http://'.$a;
    }

    $this-&gt;openid_url_identity = $a;
}
</pre>
<p>Also, during Yadis discovery, we may discover more than one provider redirect URL. The reason for this, as far as I can tell, is for load balancing or providing alternatives in case the first one we try returns an error. We&#8217;ll need to modify the code to check each endpoint&#8217;s priority level, and be prepared to retry several times in case one or more endpoints return an error response. However, that&#8217;s something for another tutorial.</p>
<p>Simple OpenID also seems to have a problem with Wordpress.com identities. It&#8217;s easy enough to solve, and you can find my solution <a href="http://www.stevelove.org/2008/08/how-to-wordpresscom-and-the-simple-openid-php-class/">here</a>.</p>
<p><a href="http://stevelove.org/projects/dope-openid/">Download</a> the version of Simple OpenID that I&#8217;m now using.</p>
]]></content:encoded>
			<wfw:commentRss>http://stevelove.org/2008/08/24/how-to-yahoo-and-the-simple-openid-php-class/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
