summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auth/OpenID/Discover.php27
-rw-r--r--Tests/Auth/OpenID/Discover_OpenID.php122
-rw-r--r--Tests/Auth/OpenID/data/test_discover_openid_ssl.xml19
3 files changed, 162 insertions, 6 deletions
diff --git a/Auth/OpenID/Discover.php b/Auth/OpenID/Discover.php
index da4a117..e72c744 100644
--- a/Auth/OpenID/Discover.php
+++ b/Auth/OpenID/Discover.php
@@ -434,11 +434,34 @@ function Auth_OpenID_discoverXRI($iname, &$fetcher)
function Auth_OpenID_discover($uri, &$fetcher)
{
+ // If the fetcher (i.e., PHP) doesn't support SSL, we can't do
+ // discovery on an HTTPS URL.
+ if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) {
+ return array($uri, array());
+ }
+
if (Auth_Yadis_identifierScheme($uri) == 'XRI') {
- return Auth_OpenID_discoverXRI($uri, $fetcher);
+ $result = Auth_OpenID_discoverXRI($uri, $fetcher);
} else {
- return Auth_OpenID_discoverURI($uri, $fetcher);
+ $result = Auth_OpenID_discoverURI($uri, $fetcher);
+ }
+
+ // If the fetcher doesn't support SSL, we can't interact with
+ // HTTPS server URLs; remove those endpoints from the list.
+ if (!$fetcher->supportsSSL()) {
+ $http_endpoints = array();
+ list($new_uri, $endpoints) = $result;
+
+ foreach ($endpoints as $e) {
+ if (!$fetcher->isHTTPS($e->server_url)) {
+ $http_endpoints[] = $e;
+ }
+ }
+
+ $result = array($new_uri, $http_endpoints);
}
+
+ return $result;
}
?> \ No newline at end of file
diff --git a/Tests/Auth/OpenID/Discover_OpenID.php b/Tests/Auth/OpenID/Discover_OpenID.php
index a09ca97..250a29e 100644
--- a/Tests/Auth/OpenID/Discover_OpenID.php
+++ b/Tests/Auth/OpenID/Discover_OpenID.php
@@ -119,7 +119,7 @@ class Tests_Auth_OpenID_Discover_FetchException extends PHPUnit_TestCase {
// Tests for openid.consumer.discover.discover
-class _DiscoveryMockFetcher {
+class _DiscoveryMockFetcher extends Auth_Yadis_HTTPFetcher {
function _DiscoveryMockFetcher(&$documents)
{
$this->redirect = null;
@@ -127,6 +127,11 @@ class _DiscoveryMockFetcher {
$this->fetchlog = array();
}
+ function supportsSSL()
+ {
+ return true;
+ }
+
function post($url, $body = null, $headers = null)
{
return $this->get($url, $headers, $body);
@@ -152,7 +157,7 @@ class _DiscoveryMockFetcher {
}
return new Auth_Yadis_HTTPResponse($final_url, $status,
- array('content-type' => $ctype), $body);
+ array('content-type' => $ctype), $body);
}
}
@@ -450,7 +455,7 @@ class Tests_Auth_OpenID_Discover_OpenID extends _DiscoveryBase {
}
}
-class _MockFetcherForXRIProxy {
+class _MockFetcherForXRIProxy extends Auth_Yadis_HTTPFetcher {
function _MockFetcherForXRIProxy($documents)
{
@@ -475,7 +480,7 @@ class _MockFetcherForXRIProxy {
$u = parse_url($url);
$proxy_host = $u['host'];
$xri = $u['path'];
- $query = $u['query'];
+ $query = Auth_OpenID::arrayGet($u, 'query');
if ((!$headers) && (!$query)) {
trigger_error('Error in mock XRI fetcher: no headers or query');
@@ -536,5 +541,114 @@ function __serviceCheck_discover_cb($url, $fetcher)
return array($url, array($__Tests_BOGUS_SERVICE));
}
+class _FetcherWithSSL extends _DiscoveryMockFetcher {
+ function supportsSSL()
+ {
+ return true;
+ }
+}
+
+class _FetcherWithoutSSL extends _DiscoveryMockFetcher {
+ function supportsSSL()
+ {
+ return false;
+ }
+}
+
+class _NonFetcher extends _DiscoveryMockFetcher {
+ var $used = false;
+
+ function _NonFetcher()
+ {
+ $a = array();
+ parent::_DiscoveryMockFetcher($a);
+ }
+
+ function supportsSSL()
+ {
+ return false;
+ }
+
+ function get($url, $headers)
+ {
+ $this->used = true;
+ }
+}
+
+class Tests_Auth_OpenID_SSLSupport extends PHPUnit_TestCase {
+ function test_discoverDropSSL()
+ {
+ // In the absence of SSL support, the discovery process should
+ // drop endpoints whose server URLs are HTTPS.
+ $id_url = 'http://bogus/';
+
+ $d = array(
+ $id_url => array('application/xrds+xml',
+ Tests_Auth_OpenID_readdata('test_discover_openid_ssl.xml'))
+ );
+
+ $f =& new _FetcherWithoutSSL($d);
+
+ $result = Auth_OpenID_discover($id_url, $f);
+
+ list($url, $services) = $result;
+
+ $this->assertTrue($url == $id_url);
+ $this->assertTrue(count($services) == 1);
+
+ $e = $services[0];
+ $this->assertTrue($e->server_url == 'http://nossl.vroom.unittest/server');
+ }
+
+ function test_discoverRetainSSL()
+ {
+ // In the presence of SSL support, the discovery process
+ // should NOT drop endpoints whose server URLs are HTTPS.
+
+ // In the absence of SSL support, the discovery process should
+ // drop endpoints whose server URLs are HTTPS.
+ $id_url = 'http://bogus/';
+
+ $d = array(
+ $id_url => array('application/xrds+xml',
+ Tests_Auth_OpenID_readdata('test_discover_openid_ssl.xml'))
+ );
+
+ $f =& new _FetcherWithSSL($d);
+
+ $result = Auth_OpenID_discover($id_url, $f);
+
+ list($url, $services) = $result;
+
+ $this->assertTrue($url == $id_url);
+ $this->assertTrue(count($services) == 2);
+
+ $e = $services[0];
+ $this->assertTrue($e->server_url == 'http://nossl.vroom.unittest/server');
+
+ $e = $services[1];
+ $this->assertTrue($e->server_url == 'https://ssl.vroom.unittest/server');
+ }
+
+ function test_discoverSSL()
+ {
+ // The consumer code should not attempt to perform discovery
+ // on an HTTPS identity URL in the absence of SSL support.
+
+ $id_url = 'https://unsupported/';
+
+ $f =& new _NonFetcher();
+
+ $result = Auth_OpenID_discover($id_url, $f);
+
+ $this->assertTrue($result == array($id_url, array()));
+ $this->assertFalse($f->used);
+ }
+}
+
+global $Tests_Auth_OpenID_Discover_OpenID_other;
+$Tests_Auth_OpenID_Discover_OpenID_other = array(
+ new Tests_Auth_OpenID_SSLSupport()
+ );
?> \ No newline at end of file
diff --git a/Tests/Auth/OpenID/data/test_discover_openid_ssl.xml b/Tests/Auth/OpenID/data/test_discover_openid_ssl.xml
new file mode 100644
index 0000000..111945c
--- /dev/null
+++ b/Tests/Auth/OpenID/data/test_discover_openid_ssl.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xrds:XRDS xmlns:xrds="xri://$xrds"
+ xmlns="xri://$xrd*($v*2.0)"
+ xmlns:openid="http://openid.net/xmlns/1.0"
+ >
+ <XRD>
+
+ <Service priority="10">
+ <Type>http://openid.net/signon/1.0</Type>
+ <URI>http://nossl.vroom.unittest/server</URI>
+ <openid:Delegate>http://smoker.myopenid.com/</openid:Delegate>
+ </Service>
+ <Service priority="11">
+ <Type>http://openid.net/signon/1.0</Type>
+ <URI>https://ssl.vroom.unittest/server</URI>
+ <openid:Delegate>http://smoker.myopenid.com/</openid:Delegate>
+ </Service>
+ </XRD>
+</xrds:XRDS>