New PHP OpenID Client/Server Implementation

Martin Atkins mart at degeneration.co.uk
Tue Sep 6 12:13:35 PDT 2005


Dan Libby wrote:
> Hi all,
> 
> I'm new to this list ( except for some lurking ), and I come bearing gifts.
> 
> Specifically, I have ported the Python OpenID library and example
> classes to PHP.  They aren't heavily tested yet, but they seem to
> interoperate okay with the Python client/server.  I have targetted PHP
> 

Attached is a small patch containing the changes I had to make firstly
to get it to run properly on my server here and to work with
LiveJournal. It also features some more general fixes. In particular:
* no SCRIPT_URI was being set on my server, so I added a best-guess fallback
* you were sending the full URL in the HTTP request line rather than
just the path component, which upset LiveJournal's mod_perl code.
(Apache by default simply disregards the scheme and host part, but
LiveJournal replaces the component that would normally do that and
doesn't handle that case)
* the return_url check was failing where there's no port number
component in the URL.

I've only tested this with your simple.php.

In addition, I think you need to be more careful with the URLs you
accept. Currently PHP's parse_url function is protecting you to a
certain extent, but you should yourself ensure that the URL components
don't feature any "unusual" characters (newlines, for example) before
just throwing them at a socket like that.

Finally, URL canonicalisation doesn't seem to be working. I'm not sure
why, but leaving off the http:// caused it to fail as did leaving off
the trailing slash on a URL which only has "/" as its path component.

I don't have any servers running PHP 4, so I can't offer any comment on
that.
-------------- next part --------------
--- examples/simple.php	Tue Sep 06 07:26:26 2005
+++ examples/simple.php	Tue Sep 06 19:34:20 2005
@@ -82,6 +82,8 @@
     
         $parts = parse_url( $return_to );
 
+        if (! isset($parts["port"])) $parts["port"] = ($parts["scheme"] == 'https' ? 443 : 80);
+
         // you should verify return_to host:port string match host and 
         // port of this server
         if( $parts['host'] != HOST || $parts['port'] != PORT ) {
@@ -170,10 +172,10 @@
             // based on your running location.  In practice this may be static.
             // You will likely want it to be your entire website, not just
             // this script.
-            $trust_root = $_SERVER['SCRIPT_URI'];
+            $trust_root = isset($_SERVER['SCRIPT_URI']) ? $_SERVER['SCRIPT_URI'] : 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
 
             // build url to application for use in creating return_to
-            $app_url = $_SERVER['SCRIPT_URI'];
+            $app_url = isset($_SERVER['SCRIPT_URI']) ? $_SERVER['SCRIPT_URI'] : 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
 
             // create return_to url from app_url
             $return_to = $handler->createReturnTo($app_url, $identity_url);
--- openid/httpclient.php	Tue Sep 06 07:23:24 2005
+++ openid/httpclient.php	Tue Sep 06 19:57:40 2005
@@ -97,9 +97,9 @@
             $scheme = isset( $parts['scheme'] ) ? $parts['scheme'] : null;
             $host = isset( $parts['host'] ) ? $parts['host'] : null;
             $port = isset( $parts['port'] ) ? $parts['port'] : ( $scheme == 'https' ? 443 : 80 );
-            $path = isset( $parts['path'] ) ? $parts['path'] : ( $scheme == 'https' ? 443 : 80 );
-            $query = isset( $parts['query'] ) ? $parts['query'] : ( $scheme == 'https' ? 443 : 80 );
-            
+            $path = isset( $parts['path'] ) ? $parts['path'] : null;
+            $query = isset( $parts['query'] ) ? $parts['query'] : null;
+
             $uri = $path . ( $query ? '?' . $query : '' );
         
             if( !in_array( $scheme, array( 'http', 'https' ) ) || !$host || !$port || !$uri ) {
@@ -111,7 +111,7 @@
     
             $user_agent = $this->user_agent;
         	$headers = 
-                "GET $url HTTP/1.0\r\n" .
+                "GET $path HTTP/1.0\r\n" .
                 "User-Agent: $user_agent\r\n" .
                 "Host: $host\r\n" .
                 "Cache-Control: no-cache\r\n" .


More information about the yadis mailing list